linux的信令

来源:互联网 发布:mac桌面图标怎么靠左 编辑:程序博客网 时间:2024/05/03 19:02

这里写图片描述

一, kill,alarm,abort函数的使用

kill函数的使用列子

/*************************************************************************    > File Name: kill.c    > Author: songli    > QQ: 2734030745    > Mail: 15850774503@163.com    > CSDN: http://my.csdn.net/Poisx    > github: https://github.com/chensongpoixs    > Created Time: Sun 22 Oct 2017 10:48:34 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <signal.h>#include <sys/stat.h>#include <unistd.h>int main(int argc, char *argv[]){    //pcb进程块pid    pid_t pid;    //创建子进程    pid = fork();    if (pid < 0) //异常处理    {        perror("fork error");        return -1;    }    else if (pid > 0) //父进程的处理    {        printf("fahter fpid:%d, cpid:%d\n", getpid(), pid);        while (1)        {            sleep(1);        }    }    else if (pid == 0) //子线程的处理    {        printf("child  fpid:%d, cpid:%d\n", getppid(), getpid());        //子线程通知父线程        kill(getppid(), SIGKILL);        while (1)        {            sleep(1);        }    }    return 0;}

这里写图片描述

raise函数的使用

/*************************************************************************    > File Name: raise.c    > Author: songli    > QQ: 2734030745    > Mail: 15850774503@163.com    > CSDN: http://my.csdn.net/Poisx    > github: https://github.com/chensongpoixs    > Created Time: Sun 22 Oct 2017 11:03:18 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <signal.h>int main(int argc, char *argv[]){    //PCB 进程块pid    pid_t pid;    //创建子进程    pid = fork();    if (pid < 0) //异常处理    {        perror("fork error");        return -1;    }    else if (pid > 0) //父进程的处理    {        printf("father fpid:%d, cpid:%d\n", getpid(), pid);        while (1)        {            sleep(1);        }    }    else if (pid == 0) //子线程的处理    {        printf("child fpid:%d, cpid:%d\n", getppid(), getpid());        //第一参数进程id  通知的进程id        int ret = raise(getppid());        if (ret == 0)        {            printf("ok\n");        }        while (1)        {            sleep(1);        }    }    return 0;}

这里写图片描述

abort函数的使用

/*************************************************************************    > File Name: abort.c    > Author: songli    > QQ: 2734030745    > Mail: 15850774503@163.com    > CSDN: http://my.csdn.net/Poisx    > github: https://github.com/chensongpoixs    > Created Time: Sun 22 Oct 2017 11:13:43 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <signal.h>//call backvoid signalhandler(int signo){    printf("signo:%d\n", signo);}int main(int argc, char *argv[]){    //定义信令集结构体赋值操作    struct sigaction act;    //回调函数的处理    act.sa_handler = signalhandler;    //清空未信令集的信令    sigemptyset(&act.sa_mask);    //赋值到block信令集中     sigaddset(&act.sa_mask, SIGABRT);    // 调用函数signal    // abort 函数的信号是 SIGABRT    sigaction(SIGABRT, &act, NULL);    abort();    return 0;}

这里写图片描述

二,计时器的alarm和setitimer函数

alarm时候的使用

/*************************************************************************    > File Name: alarm.c    > Author: songli    > QQ: 2734030745    > Mail: 15850774503@163.com    > CSDN: http://my.csdn.net/Poisx    > github: https://github.com/chensongpoixs    > Created Time: Sun 22 Oct 2017 11:24:05 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <signal.h>/** *计时器的使用 * */void signalhandler(int signo){    printf("signal:%d\n", signo);}int main(int argc, char *argv[]){    // alarm 函数的signal是SIGALRM    signal(SIGALRM, signalhandler);    int ret;    //返回值的上一计时器的时间    alarm(1);    ret = alarm(3);    printf("ret :%d\n", ret);    sleep(5);    return 0;}

这里写图片描述

setitimer函数的使用

/*************************************************************************    > File Name: setitimer.c    > Author: songli    > QQ: 2734030745    > Mail: 15850774503@163.com    > CSDN: http://my.csdn.net/Poisx    > github: https://github.com/chensongpoixs    > Created Time: Sun 22 Oct 2017 11:32:32 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/time.h>#include <sys/types.h>#include <sys/stat.h>#include <signal.h>/** * *计时器的使用 * */void signalhandler(int signo){    printf("signal:%d, 数据\n", signo );}int main(int argc, char *argv[]){    //回调函数信令    signal(SIGALRM, signalhandler);    //周期函数的结构体    struct itimerval tm;    //设置周期    tm.it_interval.tv_sec = 1; //周期的设置    tm.it_interval.tv_usec = 0;    //下一个时间的周期    tm.it_value.tv_sec = 1;    tm.it_value.tv_usec = 0;    //计时器    setitimer(ITIMER_REAL, &tm, NULL );    while (1)    {        sleep(1);    }    return 0;}

三,自定义信令集block信令集

这里写图片描述

函数

 int sigemptyset(sigset_t *set);       int sigfillset(sigset_t *set);       int sigaddset(sigset_t *set, int signum);       int sigdelset(sigset_t *set, int signum);       int sigismember(const sigset_t *set, int signum);       int sigprocmask(int how, const sigset_t *set, sigset_t  *old‐       set);

信号集操作相关函数
1. 概念:
未决信号集:
没有被当前进程处理的信号
阻塞信号集:
将某个信号放到阻塞信号集,这个信号就不会被进程处理
阻塞解除之后,信号被处理
2. 自定义信号集
int sigemptyset(sigset_t *set); 将set集合置空
int sigfillset(sigset_t *set); 将所有信号加入set集合
int sigaddset(sigset_t *set,int signo);
§ 将signo信号加入到set集合
int sigdelset(sigset_t *set,int signo);
§ 从set集合中移除signo信号
int sigismember(const sigset_t *set,int signo);
§ 判断信号是否存在
3. sigprocmask函数
屏蔽或者是解除信号屏蔽, 将自定义信号集设置给阻塞信号集
函数原型:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
4. sigpending – 读取当前进程的未决信号集
函数原型: int sigpending(sigset_t *set);
参数: set – 内核将未决信号集写入set

/*************************************************************************> File Name: sigchld.c> Author: songli> QQ: 2734030745> Mail: 15850774503@163.com> CSDN: http://my.csdn.net/Poisx> github: https://github.com/chensongpoixs> Created Time: Sun 22 Oct 2017 11:51:31 PM CST************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <signal.h>#define SIGPID 1//call backvoid signalhandler(int signo){    // PCB pid    pid_t wpid;#if SIGPID    while (1)    {#endif        wpid = waitpid(-1, NULL, WNOHANG);        if (wpid > 0) //退出子进程的操作        {            printf("退出子进程的操作:wpid:%d, signal:%d\n", wpid, signo);        }        else if (wpid == -1) // 没有子线程的操作        {            printf("没有子进程的操作:wpid:%d, signal:%d\n", wpid, signo);            exit(0);        }        else if (wpid == 0) //有子线程的操作        {            printf("有子进程的操作:wpid:%d, signal:%d\n", wpid, signo);            break;        }#if SIGPID    }#endif}int main(int argc, char *argv[]){    //pcb 进程块 pid    pid_t pid;    int i, n = 3;    #if SIGPID     //设置阻塞信令集    sigset_t mask;    //清空信令集的数据    sigemptyset(&mask);    //赋值block信令集的操作    sigaddset(&mask, SIGCHLD);    //设置阻塞    sigprocmask(SIG_BLOCK, &mask, NULL);    #endif    for (i = 0; i < 3; i++)    {        //创建子进程        pid = fork();        if (pid < 0) //异常处理        {            perror("fork error");            return -1;        }        else if (pid > 0) //父进程的处理        {            printf("fahter fpid:%d, cpid:[%d]\n", getpid(), pid);        }        else if (pid == 0) // 子进程的处理        {            printf("child fpid:%d, cpid:[%d]\n", getppid(), getpid());            break; //防止子线程创建子线程        }    }    //============       子线程操作           ===============    if (i < n)    {        printf("no child %d, cpid[%d]\n", i, getpid());        return 2;    }    //===========          父进程的操作     ================    if (i == n)    {        printf("no father %d, fpid[%d]\n", i, getpid());        //信令结构体        struct sigaction act;        //回调函数        act.sa_handler = signalhandler;        //清空信令集的数据        sigemptyset(&act.sa_mask);        //赋值        sigaddset(&act.sa_mask, SIGCHLD);        sigaction(SIGCHLD, &act, NULL);        #if SIGPID        //解除block信令的阻塞事件        sigprocmask(SIG_UNBLOCK, &mask, NULL);        #endif        while (1)        {            sleep(1);        }    }    return 0;}

这里写图片描述