10_信号发送函数kill()和raise()

信号发送

Kill基本用法
发送信号的函数有kill和raise
区别:kill既可以向自身发送信号,也可以向其他进程发送信号;
raise函数向进程自身发送信号。
Int kill(pid_t pid, int siq) 
int raise(int signo)

Int kill(pid_t pid, int siq)
参数组合情况解释:
kill(pid_t pid, int siq)
    pid>0 将信号sig发给pid进程
    pid=0 将信号sig发给同组进程
    pid=-1 将信号sig发送给所有进程,调用者进程有权限发送的每一个进程(除了1号进程之外,还有它自身)
    pid<-1 将信号sig发送给进程组是pid(绝对值)的每一个进程

子进程向父进程发送信号
sleep函数几点说明
1sleep函数作用,让进程睡眠。
2)能被信号打断,然后处理信号函数以后,就不再睡眠了,直接向下执行代码.
3sleep函数的返回值,是剩余的秒数
1、当一个进程调用fork()时,其子进程继承父进程的信号处理方式
因为子进程在开始时复制了父进程的进程映像,所以信号捕捉函数的地址
在子进程中是有意义的!
#include <stdio.h>
#include <errno.h>
#include <signal.h>

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
/*
    kill()函数与sleep()函数的使用
*/

//信号处理函数
void  myhandle(int num)
{
    if (num == SIGINT)
    {
        printf("recv signal SIGINT \n");
    }
    else if (num == SIGUSR1)
    {
        printf("recv signal SIGUSR1 \n");
    }
    else
    {
        printf("recv signal id num : %d \n", num);
    }
}

int main(void)
{

    pid_t   pid;
    printf("main ....begin\n");
    //如果在fork之前安装信号,则子进程可以继承信号。
    //安装信号 SIGINT
    if (signal(SIGINT, myhandle) == SIG_ERR)
    {
        perror("func signal err\n");
        return 0;
    } 
    //安装信号SIGUSER1
    if (signal(SIGUSR1, myhandle) == SIG_ERR)
    {
        perror("func signal err\n");
        return 0;
    } 

    pid = fork();
    if (pid == -1)
    {
        printf("fork err....\n");
        return 0;
    }

    #if 0
    if (pid == 0)
    {
        pid = getppid();
        kill(pid, SIGUSR1); //向老爹发信号
        //raise(pid);//等价
        exit(0);//子进程运行完就退出了
    }
    /*
    运行结果:
    hzmct@U-64:/study/linuxtest/day02/01signal$ ./dm03_signal
    main ....begin
    父进程开始睡眠
    recv signal SIGUSR1 
    父进程开始唤醒
    父进程开始睡眠
    父进程开始唤醒
    sleep 函数执行完毕以后返回..
    */
    #endif
//---------------------------------------------------


    //子进程向同组进程发送信号,父进程和子进程都收到了信号,证明了信号的继承性
#if 0
    //因为信号处理函数注册是在fork()之前,父进程注册信号同时
    //子进程也注册了此信号,因此信号处理函数会打印2遍
    if (pid == 0)
    {
        pid = getppid();
        kill(0, SIGUSR1); //向进程组发信号
        exit(0);
    }
        /*
    运行结果:
    hzmct@U-64:/study/linuxtest/day02/01signal$ ./dm03_signal
    main ....begin
    父进程开始睡眠
    recv signal SIGUSR1 
    recv signal SIGUSR1 
    父进程开始唤醒
    父进程开始睡眠
    父进程开始唤醒
    sleep 函数执行完毕以后返回...
    */
#endif

//----------------------------------------------------
//子进程向 同组进程 发送信号
#if 0
    //因为信号处理函数注册是在fork()之前,父进程注册信号同时
    //子进程也注册了此信号,因此信号处理函数会打印2遍
    if (pid == 0)
    {
        pid = getppid();
        kill(0, SIGUSR1); //向进程组发信号
        exit(0);
    }
        /*
    运行结果:
    hzmct@U-64:/study/linuxtest/day02/01signal$ ./dm03_signal
    main ....begin
    父进程开始睡眠
    recv signal SIGUSR1 
    recv signal SIGUSR1 
    父进程开始唤醒
    父进程开始睡眠
    父进程开始唤醒
    sleep 函数执行完毕以后返回...
    */
#endif
//---------------------------
//子进程向进程组发送信号
    #if 1
    if (pid == 0)
    {
        //获取进程组id
        pid = getpgrp();
        //向进程组发送信号
        killpg(pid, SIGUSR1);
        exit(0);
    }
    #endif
/*
运行结果
main ....begin
父进程开始睡眠
recv signal SIGUSR1 
父进程开始睡眠
recv signal SIGUSR1 
父进程开始唤醒
sleep 函数执行完毕以后返回...
*/
//-------------------------------------------------
int n = 3;
    do 
    {
        printf("父进程开始睡眠\n");
        n = sleep(n);//sleep函数返回剩余的秒数
        printf("父进程开始唤醒\n");
    } while (n > 0);
    //请思考sleep函数的作用 man sleep
    printf("sleep 函数执行完毕以后返回...\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/WUZHU2017/article/details/81876964