Linux 编程之【进程】signal

【说明】

kill,可以向包括本身在内的进程发送一个信号。
kill有一个变体叫 killall,可以给运行着某一命令的所有进程发送信号。
pause,将程序挂起直到有一个信号出现为止。
程序中信号的使用会带来一个特殊的问题:如果信号出现在系统调用的执行过程中会发生什么情况?
答案是不确定的。
因此,在程序中使用信号,需要注意一些系统调用会因为接收到一个信号而失败,而这种错误情况
可能是在添加信号处理函数之前没有考虑的。
在编写程序中处理信号部分的代码时必须非常小心,因为在使用信号的程序中会出现各种各样的
“竞态条件”。例如,如果想调用 pause 等待一个信号,可信号却出现在调用 pause 之前,就会使
程序无限期地等待一个不会发生的事件。

【示例】

#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>

void sig_alm(int sig)
{
    pid_t p;
    p = getpid();
	
    printf("### Process(%d) receive a alarm signal.\r\n", p);
	
    return;
}

int main(int argc, char *argv[])
{
    pid_t pid,wpid,pid_self,ppid;
    char message[64] = {0};
    int n, val;
  
    (void)signal(SIGALRM, sig_alm);
  
    printf("[parent]start to fork child process.\r\n");
    pid = fork();
    switch(pid)
    {
  	case -1:
  	    perror("fork failed");
  	    exit(1);
  		
  	case 0:
  	    pid_self = getpid();
  	    sprintf(message, "[child]This is the child process(%d)", pid_self);
  	    for(n=5; n>0; n--)
 	    {
 	      puts(message);
 	      sleep(1);
 	    }
 	    
 	    ppid = getppid();
 	    printf("[child] signal: child > parent\r\n");
 	    kill(ppid, SIGALRM);
 	    
 	    printf("[child]child process(%d) exit.\r\n", pid_self);
  	    break;
  		
  	default:
  	    pid_self = getpid();
  	    sprintf(message, "[parent]This is the parent process(%d)", pid_self);
  	    for(n=3; n>0; n--)  //for(n=8;n>0;n--)
 	    {
 	        puts(message);
 	        sleep(1);
 	    }

 	    //pause();
 	    printf("[parent] signal: parent > child\r\n");
 	    kill(pid, SIGALRM);
 	    
 	    wpid = wait(&val);
 	    printf("[parent]wait_pid=%d, child_pid=%d \r\n", wpid, pid);
 	    printf("[parent]parent process(%d) exit. \r\n", pid_self);
  	    break;
    }
  
    exit(0);
}


【编译及执行】

(1) 原码执行效果
# gcc -o signal signal.c
# ./signal
[parent]start to fork child process.
[parent]This is the parent process(8964)
[child]This is the child process(8965)
[parent]This is the parent process(8964)
[child]This is the child process(8965)
[parent]This is the parent process(8964)
[child]This is the child process(8965)
[parent] signal: parent > child
### Process(8965) receive a alarm signal.
[child]This is the child process(8965)
[child]This is the child process(8965)
[child] signal: child > parent
### Process(8964) receive a alarm signal.
[child]child process(8965) exit.
[parent]wait_pid=8965, child_pid=8965 
[parent]parent process(8964) exit. 

(2) 若在父进程向子进程发送信号之前,先挂起一下(pause),其执行的效果如下:
# ./signal
[parent]start to fork child process.
[parent]This is the parent process(9608)
[child]This is the child process(9609)
[parent]This is the parent process(9608)
[child]This is the child process(9609)
[parent]This is the parent process(9608)
[child]This is the child process(9609)
[child]This is the child process(9609)
[child]This is the child process(9609)
[child] signal: child > parent
### Process(9608) receive a alarm signal.
[parent] signal: parent > child
### Process(9609) receive a alarm signal.
[child]child process(9609) exit.
[parent]wait_pid=9609, child_pid=9609 
[parent]parent process(9608) exit. 

(3) 若将父进程中的for循环次数改为8,即达到在父进程pause之前,子进程已经将信号发送,
      则程序执行的效果如下(父进程会无限期的等待下去):
# ./signal
[parent]start to fork child process.
[parent]This is the parent process(9623)
[child]This is the child process(9624)
[parent]This is the parent process(9623)
[child]This is the child process(9624)
[parent]This is the parent process(9623)
[child]This is the child process(9624)
[parent]This is the parent process(9623)
[child]This is the child process(9624)
[parent]This is the parent process(9623)
[child]This is the child process(9624)
[parent]This is the parent process(9623)
[child] signal: child > parent
### Process(9623) receive a alarm signal.
[parent]This is the parent process(9623)
[child]child process(9624) exit.
[parent]This is the parent process(9623)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值