linux基础复习(8)进程通信
按照下列三种方式中的一种进行操作。
(1) 忽略此信号。大多数信号都可使用这种方式进行处理,但有两种信号却决不能被忽略。它们是:SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供一种使进程终止或停止的可靠方法。另外,如果忽略某些由硬件异常产生的信号(例如非法存储访问或除以0),则进程的行为是未定义的。
(2) 捕捉信号。为了做到这一点要通知内核在某种信号发生时,调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行的处理。如果捕捉到SIGCHLD信号,则表示子进程已经终止,所以此信号的捕捉函数可以调用waitpid以取得该子进程的进程ID以及它的终止状态。
(3) 执行系统默认动作。对大多数信号的系统默认动作是终止该进程。
每一个信号都有一个缺省动作,它是当进程没有给这个信号指定处理程序时,内核对信号的处理。有5种缺省的动作:
n 异常终止(abort):在进程的当前目录下,把进程的地址空间内容、寄存器内容保存到一个叫做core的文件中,而后终止进程。
n 退出(exit):不产生core文件,直接终止进程。
n 忽略(ignore):忽略该信号。
n 停止(stop):挂起该进程。
n 继续(continue):如果进程被挂起,则恢复进程的运行。否则,忽略信号。
[b]信号发送与捕捉[/b]
kill()和raise()
kill()不仅可以中止进程,也可以向进程发送其他信号。
与kill函数不同的是,raise()函数运行向进程自身发送信号。
#i nclude
#i nclude
int kill(pid_t pid, int signo) ;
int raise(int signo) ;
两个函数返回:若成功则为0,若出错则为-1。
kill的pid参数有四种不同的情况:
n pid>0 将信号发送给进程ID为pid的进程。
n pid == 0 将信号发送给其进程组I D等于发送进程的进程组ID,而且发送进程有许可权向其发送信号的所有进程。
n pid 将信号发送给其进程组ID等于pid绝对值,而且发送进程有许可权向其发送信号的所有进程。如上所述一样,“所有进程”并不包括系统进程集中的进程。
n pid ==-1 POSIX.1未定义此种情况。
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
int main()
{
pid_t pid;
int ret;
if((pid=fork())0){
perror(fork);
exit(1);
}
if(pid == 0){
raise(SIGSTOP);
exit(0);
}
else{
printf(pid=%d\n,pid);
if((waitpid(pid,NULL,WNOHANG))==0){
if((ret=kill(pid,SIGKILL))==0)
printf(kill %d\n,pid);
else{
perror(kill);
}
}
}
}
使用alarm函数可以设置一个时间值(闹钟时间),在将来的某个时刻该时间值会被超过。当所设置的时间值被超过后,产生SIGALRM信号。如果不忽略或不捕捉此信号,则其默认动作是终止该进程。
#i nclude
unsigned int alarm(unsigned int seconds) ;
返回:0或以前设置的闹钟时间的余留秒数
参数seconds的值是秒数,经过了指定的seconds秒后会产生信号SIGALRM。
每个进程只能有一个闹钟时间。如果在调用alarm时,以前已为该进程设置过闹钟时间,而且它还没有超时,则该闹钟时间的余留值作为本次alarm函数调用的值返回。以前登记的闹钟时间则被新值代换。
如果有以前登记的尚未超过的闹钟时间,而且seconds值是0,则取消以前的闹钟时间,其余留值仍作为函数的返回值。
pause函数使调用进程挂起直至捕捉到一个信号。
#i nclude
int pause(void);
返回:-1,errno设置为EINTR
只有执行了一个信号处理程序并从其返回时,pause才返回。
#i nclude
#i nclude
#i nclude
int main()
{
int ret;
ret=alarm(5);
pause();
printf(I have been waken up.\n,ret);
}
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)