Linux 信号:signal 与 sigaction
0.Linux下查看支持的信号列表:
france@Ubuntux64:~$ kill -l
) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP
) SIGABRT ) SIGBUS ) SIGFPE ) SIGKILL ) SIGUSR1
) SIGSEGV ) SIGUSR2 ) SIGPIPE ) SIGALRM ) SIGTERM
) SIGSTKFLT ) SIGCHLD ) SIGCONT ) SIGSTOP ) SIGTSTP
) SIGTTIN ) SIGTTOU ) SIGURG ) SIGXCPU ) SIGXFSZ
) SIGVTALRM ) SIGPROF ) SIGWINCH ) SIGIO ) SIGPWR
) SIGSYS ) SIGRTMIN ) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+
) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+
) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMIN+
) SIGRTMIN+ ) SIGRTMIN+ ) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX-
) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX-
) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX- ) SIGRTMAX-
) SIGRTMAX- ) SIGRTMAX
0.1 可靠信号与不可靠:
列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。见2.
0.2信号说明
) SIGHUP
本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。
登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个 Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。
此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。
) SIGINT
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
) SIGQUIT
和SIGINT类似, 但由QUIT字符(通常是Ctrl-/)(按键应为Ctrl+)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。
) SIGILL
执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行数据段. 堆栈溢出时也有可能产生这个信号。
) SIGTRAP
由断点指令或其它trap指令产生. 由debugger使用。
) SIGABRT
调用abort函数生成的信号。
) SIGBUS
非法地址, 包括内存地址对齐(alignment)出错。比如访问一个四个字长的整数, 但其地址不是4的倍数。它与SIGSEGV的区别在于后者是由于对合法存储地址的非法访问触发的(如访问不属于自己存储空间或只读存储空间)。
) SIGFPE
在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误。
) SIGKILL
用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。
) SIGUSR1
留给用户使用
) SIGSEGV
试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.
) SIGUSR2
留给用户使用
) SIGPIPE
管道破裂。这个信号通常在进程间通信产生,比如采用FIFO(管道)通信的两个进程,读管道没打开或者意外终止就往管道写,写进程会收到SIGPIPE信号。此外用Socket通信的两个进程,写进程在写Socket的时候,读进程已经终止。
) SIGALRM
时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号.
) SIGTERM
程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。
) SIGCHLD
子进程结束时, 父进程会收到这个信号。
如果父进程没有处理这个信号,也没有等待(wait)子进程,子进程虽然终止,但是还会在内核进程表中占有表项,这时的子进程称为僵尸进程。这种情 况我们应该避免(父进程或者忽略SIGCHILD信号,或者捕捉它,或者wait它派生的子进程,或者父进程先终止,这时子进程的终止自动由init进程来接管)。
) SIGCONT
让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用一个handler来让程序在由stopped状态变为继续执行时完成特定的工作. 例如, 重新显示提示符...
) SIGSTOP
停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别:该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.
) SIGTSTP
停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时(通常是Ctrl-Z)发出这个信号
) SIGTTIN
当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN信号. 缺省时这些进程会停止执行.
) SIGTTOU
类似于SIGTTIN, 但在写终端(或修改终端模式)时收到.
) SIGURG
有"紧急"数据或out-of-band数据到达socket时产生.
) SIGXCPU
超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变。
) SIGXFSZ
当进程企图扩大文件以至于超过文件大小资源限制。
) SIGVTALRM
虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.
) SIGPROF
类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的时间.
) SIGWINCH
窗口大小改变时发出.
) SIGIO
文件描述符准备就绪, 可以开始进行输入/输出操作.
) SIGPWR
Power failure
) SIGSYS
非法的系统调用。
0.3 注意点
在以上列出的信号中,程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP
不能恢复至默认动作的信号有:SIGILL,SIGTRAP
默认会导致进程流产的信号有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ
默认会导致进程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM
默认会导致进程停止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU
默认进程忽略的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH
此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在进程挂起时是继续,否则是忽略,不能被阻塞。 )有两个信号可以停止进程:SIGTERM和SIGKILL。 SIGTERM比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。在某些情况下,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。 )对于SIGKILL信号,进程是不能忽略的。这是一个 “我不管您在做什么,立刻停止”的信号。假如您发送SIGKILL信号给进程,Linux就将进程停止在那里。
1.1 signal:用法简单
#include <signal.h> void (*signal(int signum, void (*handler))(int)))(int);
如果该函数原型不容易理解的话,可以参考下面的分解方式来理解:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler));
第一个参数指定信号的值,第二个参数指定针对前面信号值的处理,可以忽略该信号(参数设为SIG_IGN);SIGSTOP/SIGKILL这俩信号无法捕获和忽略
可以采用系统默认方式处理信号(参数设为SIG_DFL);也可以自己实现处理方式(参数指定一个函数地址)。
如果signal()调用成功,返回最后一次为安装信号signum而调用signal()时的handler值;失败则返回SIG_ERR。
demo:
/*实现进程的软中断通信*/
/*按Ctrl+c键,可发送SIGINT信号给当前进程*/
/*使用系统调用fork()创建两个子程序,再用系统调用signal()注册父进程和子进程分别对待从键盘上来的中断信号(SIGINT信号)的行为;当有中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程收到信号后分别输出
Child Processll is Killed by Parent!
Child Processl2 is Killed by Parent!
父进程等待两个子进程终止后,输出如下的信息后终止:
Parent process is Killed!
*/ #include<stdio.h>
#include<signal.h>
#include <stdlib.h> int wait_mark; void waiting()
{
while(wait_mark==);
}
void stop()
{
wait_mark=;
} int main()
{
int p1,p2;
while((p1=fork())==-);//创建子进程1如出错会进入循环
if(p1==)
{
wait_mark=;
signal(SIGINT,SIG_IGN);//注册SIGINT信号发生后的行为(忽略)
signal(,stop);//注册16号信号发生后的处理函数
waiting();
printf("Child Process 1 is Killed by Parent!\n");
exit();
}
else
{
while((p2=fork())==-);//创建子进程2如出错会进入循环
if(p2==)
{
wait_mark=;
signal(SIGINT,SIG_IGN);//注册SIGINT信号发生后的行为(忽略)
signal(,stop);//注册17号信号发生后的处理函数
waiting(); printf("Child Process 2 is Killed by Parent!\n"); exit();
}
else
{
wait_mark=;
signal(SIGINT,stop);//注册SIGINT信号发生后的处理函数
waiting();
kill(p1,);//发送16号信号给p1
kill(p2,);//发送17号信号给p1
wait();
wait();
printf("Parent Process is Killed!\n");
exit();
}
}
}
france@Ubuntux64:~$ ./h4
Child Process 1 is Killed by Parent!
Child Process 2 is Killed by Parent!
Parent Process is Killed!
2.1.1信号堵塞
经过实验发现,signal函数会堵塞当前正在处理的signal,但是没有办法阻塞其它signal。
比如正在处理SIG_INT,再来一个SIG_INT则会堵塞,但是来SIG_QUIT则将SIG_INT其中断,如果SIG_QUIT有处理,则需要等待SIG_QUIT处理完了,SIG_INT才会接着刚才处理。(如果这SIG_QUIT开始处理的时候再来个SIG_INT的算下面这种情况¥2)
同理处理SIG_QUIT碰到对应情况也一样。
注:
¥2.只有信号处理函数处理完毕,才会对后来的SIGINT再进行处理,同时后续无论来多少个SIGINT,仅处理一个SIGINT 如下
france@Ubuntux64:~$ ./h7
^C
0 Enter SignHandlerNew,signo:2.
^C //同信号 被堵塞
^\
1 Enter SignHandlerNew,signo:3. //SIG_INT被中断
^C //由于已经有SIG_INT在等待 被堵塞
^C //同时后续无论来多少个SIGINT,仅处理一个SIGINT
1 Leave SignHandlerNew,signo:3 //SIG_QUIT处理完毕
0 Leave SignHandlerNew,signo:2 //处理第一个SIG_INT
2 Enter SignHandlerNew,signo:2. //原被堵塞SIG_INT开始处理
^\
3 Enter SignHandlerNew,signo:3.
^C
3 Leave SignHandlerNew,signo:3 //效果同上
2 Leave SignHandlerNew,signo:2
4 Enter SignHandlerNew,signo:2.
4 Leave SignHandlerNew,signo:2
/*sigaction系统调用的使用方法。sigaction函数的功能是检查或修改与制定信号相关联的处理动作,可以完全代替signal函数*/ #include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h> int g_iSeq=; void SignHandlerNew(int iSignNo)
{
int iSeq=g_iSeq++;
printf("%d Enter SignHandlerNew,signo:%d.\n",iSeq,iSignNo);
sleep(); /*睡眠3秒钟*/
printf("%d Leave SignHandlerNew,signo:%d\n",iSeq,iSignNo);
} int main(void)
{
char szBuf[]; /*输入缓冲区,长度为20*/
int iRet;
// signal(SIGINT,SIG_IGN);//注册SIGINT信号发生后的行为(忽略)
signal(SIGINT,SignHandlerNew);//注册16号信号发生后的处理函数
signal(SIGQUIT,SignHandlerNew);//注册16号信号发生后的处理函数
// struct sigaction act; /*包含信号处理动作的结构体*/
// act.sa_sigaction=SignHandlerNew; /*指定信号处理函数*/
// act.sa_flags=SA_SIGINFO; /*表明信号处理函数由sa_sigaction指定*/
// sigemptyset(&act.sa_mask);
/*信号集处理函数,将act.sa_mask所指向的信号集清空,*/
/*即不包含任何信号*/
// sigaction(SIGINT,&act,NULL); /*注册SIGINT信号*/
// sigaction(SIGQUIT,&act,NULL); /* 注册SIGQUIT信号*/
do{
iRet=read(STDIN_FILENO,szBuf,sizeof(szBuf)-); /*从标准输入读入数据*/
if(iRet<)
{
perror("read fail.");
break; /* read出错退出*/
}
szBuf[iRet]=;
printf("Get: %s",szBuf); /*打印终端输入的字符串*/
}while(strcmp(szBuf,"quit\n")!=); /*输入"quit"时退出程序*/
return ;
}
2.2 sigaction
函数原型如下: int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
stuct sigaction
{
void (*)(int) sa_handle;
sigset_t sa_mask;
int sa_flags;
}
对sigaction做同样的测试:
/*sigaction系统调用的使用方法。sigaction函数的功能是检查或修改与制定信号相关联的处理动作,可以完全代替signal函数*/ #include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h> int g_iSeq=; void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
int iSeq=g_iSeq++;
printf("%d Enter SignHandlerNew,signo:%d.\n",iSeq,iSignNo);
sleep(); /*睡眠3秒钟*/
printf("%d Leave SignHandlerNew,signo:%d\n",iSeq,iSignNo);
} int main(void)
{
char szBuf[]; /*输入缓冲区,长度为20*/
int iRet;
struct sigaction act; /*包含信号处理动作的结构体*/
act.sa_sigaction=SignHandlerNew; /*指定信号处理函数*/
act.sa_flags=SA_SIGINFO; /*表明信号处理函数由sa_sigaction指定*/
sigemptyset(&act.sa_mask);
/*信号集处理函数,将act.sa_mask所指向的信号集清空,*/
/*即不包含任何信号*/
sigaction(SIGINT,&act,NULL); /*注册SIGINT信号*/
sigaction(SIGQUIT,&act,NULL); /* 注册SIGQUIT信号*/
do{
iRet=read(STDIN_FILENO,szBuf,sizeof(szBuf)-); /*从标准输入读入数据*/
if(iRet<)
{
perror("read fail.");
break; /* read出错退出*/
}
szBuf[iRet]=;
printf("Get: %s",szBuf); /*打印终端输入的字符串*/
}while(strcmp(szBuf,"quit\n")!=); /*输入"quit"时退出程序*/
return ;
}
代码效果是一样的,未做其他处理,运行如下
france@Ubuntux64:~$ ./h5
My PID is
^C
Enter SignHandlerNew,signo:.
^C
^\
Enter SignHandlerNew,signo:.
^C
^C
Leave SignHandlerNew,signo:
Leave SignHandlerNew,signo:
Enter SignHandlerNew,signo:.
^\
Enter SignHandlerNew,signo:.
^C
Leave SignHandlerNew,signo:
Leave SignHandlerNew,signo:
Enter SignHandlerNew,signo:.
Leave SignHandlerNew,signo:
效果一致
2.2.1 sa_mask
#include <signal.h>
#include <stdio.h>
#include <unistd.h> void ouch(int sig)
{
printf("oh, got a signal %d\n", sig); int i = ;
for (i = ; i < ; i++)
{
printf("signal func %d\n", i);
sleep();
}
} int main()
{
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGQUIT);
// act.sa_flags = SA_RESETHAND;
// act.sa_flags = SA_NODEFER;
act.sa_flags = ; sigaction(SIGINT, &act, ); struct sigaction act_2;
act_2.sa_handler = ouch;
sigemptyset(&act_2.sa_mask);
act.sa_flags = ;
sigaction(SIGQUIT, &act_2, ); while()
{
sleep();
}
return; }
sa_mask,信号屏蔽集,可以通过函数sigemptyset/sigaddset等来清空和增加需要屏蔽的信号,上面代码中,对信号SIGINT处理时,如果来信号SIGQUIT,SIGQUIT将被屏蔽,但是如果在处理SIGQUIT,来了SIGINT,则首先处理SIGINT,然后接着处理SIGQUIT
sa_flags如果取值为0,则表示默认行为。还可以取如下俩值:暂时未用过,不知道怎么用
SA_NODEFER,如果设置来该标志,则不进行当前处理信号到阻塞
SA_RESETHAND,如果设置来该标志,则处理完当前信号后,将信号处理函数设置为SIG_DFL行为
3.
1)进程fork()函数的使用与理解
2)signal()简单信号安装
3)sigaction() 信号安装及信号屏蔽集的使用,理解信号堵塞
4)理解信号的处理过程
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
int g_iSeq=;
int wait_mark; void waiting()
{
while(wait_mark==);
}
void stop()
{
wait_mark=;
}
void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
int iSeq=g_iSeq++;
printf("pid:%d %d Enter SignHandlerNew,signo:%d.\n",getpid(),iSeq,iSignNo); sleep(); /*睡眠3秒钟*/
printf("pid:%d %d Leave SignHandlerNew,signo:%d\n",getpid(),iSeq,iSignNo); } int main(void)
{
char szBuf[]; /*输入缓冲区,长度为20*/
int iRet;
int childp,gchildp;
printf("\ni am main Process pid:%d\n",getpid());
struct sigaction act; /*包含信号处理动作的结构体*/
act.sa_sigaction=SignHandlerNew; /*指定信号处理函数*/
act.sa_flags=SA_SIGINFO; /*表明信号处理函数由sa_sigaction指定*/
sigemptyset(&act.sa_mask);
/*信号集处理函数,将act.sa_mask所指向的信号集清空,*/
/*即不包含任何信号*/
sigaddset(&act.sa_mask, SIGQUIT); //屏蔽SIGQUIT信号
// act.sa_flags = SA_RESETHAND;
// act.sa_flags = SA_NODEFER;
act.sa_flags = ;
sigaction(SIGINT,&act,NULL); /*注册SIGINT信号*/
sigaction(SIGQUIT,&act,NULL); /* 注册SIGQUIT信号*/
if((childp=fork())<) /*创建新的子进程*/
{
perror("fork"); /*错误处理*/
exit();
} if(childp==) /*子进程*/
{
printf("\ni am child Process pid:%d\n",getpid());
if((gchildp=fork())<) /*创建新的子进程*/
{
perror("fork");
exit();
}
if(gchildp==)
{
printf("\ni am grandchild Process pid:%d\n",getpid());
if(execl("/bin/ls","ls","-l",(char *))==-) /*转去执行ls -l命令并判断是否出错 如果执行成功将从新的main函数入口开始执行 是否可以理解为直接return?*/
{
perror("execl");
exit();
}
else{
//不会执行这句
printf("\ngrandchild Process pid:%d is return\n",getpid());
} }
wait_mark=;
signal(SIGQUIT,stop);//child Process注册SIGQUIT号信号发生后的处理函数
waiting();
printf("Child Process 1 is Killed by Parent!\n");
exit(); }
do{
iRet=read(STDIN_FILENO,szBuf,sizeof(szBuf)-); /*从标准输入读入数据*/
if(iRet<)
{
perror("read fail.");
break; /* read出错退出*/
}
szBuf[iRet]=;
printf("Get: %s",szBuf); /*打印终端输入的字符串*/
}while(strcmp(szBuf,"quit\n")!=); /*输入"quit"时退出程序*/
return ;
}
france@Ubuntux64:~$ ./mya i am main Process pid: i am child Process pid: i am grandchild Process pid:
total
-rwxrwxr-x france france Sep : mya
-rw-rw-r-- france france Sep : mya.c
drwxr-xr-x france france Sep : Pictures
drwxr-xr-x france france Sep : Public
drwxr-xr-x france france Sep : Templates
drwxr-xr-x france france Sep : Videos ^C
pid: Enter SignHandlerNew,signo:.
pid: Enter SignHandlerNew,signo:. ^C //堵塞
^C //多个将被忽略
^C //多个将被忽略
pid: Leave SignHandlerNew,signo:
pid: Enter SignHandlerNew,signo:.
pid: Leave SignHandlerNew,signo:
pid: Enter SignHandlerNew,signo:.
^\ //被屏蔽,等待SIGINT信号处理完毕
^\ //被忽略
^C //被堵塞
pid: Leave SignHandlerNew,signo:
pid: Enter SignHandlerNew,signo:.
pid: Leave SignHandlerNew,signo:
pid: Enter SignHandlerNew,signo:.
^C //被堵塞
pid: Leave SignHandlerNew,signo:
pid: Enter SignHandlerNew,signo:.
pid: Leave SignHandlerNew,signo:
pid: Enter SignHandlerNew,signo:. pid: Leave SignHandlerNew,signo:
//主进程2922SIGINT信号处理完毕 开始处理SIGQUIT
pid: Enter SignHandlerNew,signo:. pid: Leave SignHandlerNew,signo:
//子进程2923SIGINT信号处理完毕 接收到SIGQUIT信号
//接收到信号后 kill itself 不进行处理
Child Process is Killed by Parent!
pid: Leave SignHandlerNew,signo:
收获了一点:
sigaction中设置屏蔽集(SIGQUIT),是针对信号来说的,所以通过signal安装的子进程也会得到这个信号屏蔽集
未完待续...
参考:
Linux 信号:signal 与 sigaction的更多相关文章
- linux 信号signal和sigaction理解
今天看到unp时发现之前对signal到理解实在浅显,今天拿来单独学习讨论下. signal,此函数相对简单一些,给定一个信号,给出信号处理函数则可,当然,函数简单,其功能也相对简单许多,简单给出个函 ...
- Linux进程间通信(一): 信号 signal()、sigaction()
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
- 非常好的一篇对linux信号(signal)的解析 (转载)【转】
转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...
- Linux信号(signal)机制【转】
转自:http://gityuan.com/2015/12/20/signal/ 信号(signal)是一种软中断,信号机制是进程间通信的一种方式,采用异步通信方式 一.信号类型 Linux系统共定义 ...
- Linux 信号signal处理函数
转自:http://www.cnblogs.com/taobataoma/archive/2007/08/30/875662.html alarm(设置信号传送闹钟) 相关函数 signal,slee ...
- Linux 信号signal处理函数--转
alarm(设置信号传送闹钟)相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...
- Linux 信号signal处理机制
信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全 ...
- Linux信号signal处理机制
信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 ...
- 进程间通信之信号量、消息队列、共享内存(system v的shm和mmap)+信号signal
进程间通信方式有:System v unix提供3种进程间通信IPC:信号量.消息队列.共享内存.此外,传统方法:信号.管道.socket套接字. [注意上述6种方式只能用户层进程间通信.内核内部有类 ...
随机推荐
- 网页loading GIF图片(加载)
http://www.lanrentuku.com/gif/a/loading.html
- 死磕nginx系列--nginx 限流配置
限流算法 令牌桶算法 算法思想是: 令牌以固定速率产生,并缓存到令牌桶中: 令牌桶放满时,多余的令牌被丢弃: 请求要消耗等比例的令牌才能被处理: 令牌不够时,请求被缓存. 漏桶算法 算法思想是: 水( ...
- C#实现的协同过滤算法
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace SlopeOn ...
- Scala学习之路 (七)Scala的柯里化及其应用
一.概念 柯里化(currying, 以逻辑学家Haskell Brooks Curry的名字命名)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程.新的函数返回一个以原有第二个参数作为 ...
- Hive学习之路 (二十一)Hive 优化策略
一.Hadoop 框架计算特性 1.数据量大不是问题,数据倾斜是个问题 2.jobs 数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次 汇总,产生十几个 jobs,耗时很长.原 ...
- Mysql双主 keepalived+lvs实现mysql高可用性
MySQL复制 能够保证数据的冗余的同时可以做读写分离来分担系统压力,如果是主主复制还可以很好的避免主节点的单点故障.但是MySQL主主复制存在一些问题无法满足我们的实际需要:未提供统一访问入口来实现 ...
- shiro实战系列(十一)之Caching
Shiro 开发团队明白在许多应用程序中性能是至关重要的.Caching 是从第一天开始第一个建立在 Shiro 中的一流功 能,以确保安全操作保持尽可能的快. 然而,Caching 作为一个概念 ...
- spring amqp初步了解
Rabbitmq简介 生产者会把消息发送给RabbitMQ的交换中心(Exchange),Exchange的一侧是生产者,另一侧则是一个或多个队列,由Exchange决定一条消息的生命周期--发送给某 ...
- kubernetes 禁用虚拟内存 swapoff -a ----- 顺便复习sed 命令
1.如果不关闭swap,就会在kubeadm初始化Kubernetes的时候报错,如下图: [ERROR Swap]: running with swap on is not supported. P ...
- 写个定时任务更新svn
最近学了点shell编程,寻思锻炼下写一个.平常你学习或者看别人讲,自己不练习肯定不行,基本上一动手准出错哈哈.等自己去实践,才会知道哪里有问题,哪里容易出错,哪里要注意什么的. 因为我们每个人有自己 ...