linux的信令

这里写图片描述

一, 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 back
void 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 back
void 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;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值