进程间通信——信号

目录

1 概念

2 信号类型 

linux的基本信号类型

操作 常用的信号

3 怎么操作信号

signal

 kill

raise

alarm

pause

注意

范例1(自己用信号发送书写sleep函数实现定时炸弹) 

范例2(用信号发送书写功能检测用户是否输入,如果用户3s内没有输入,则超时一次,如果超时  3次则自动退出。)


 

1 概念

进程间通信,用来发送通知(异步通信,中断)

内核层给用户层传递消息,通过发送信号实现

硬件

同步通信:发送端和接收端,使用同一时钟通信
异步通信:发送端和接收端使用不同时钟通信

软件

同步通信:按照指定的顺序进行运行
异步通信:一种随机事件,在程序编写阶段不能够确定事件发生的时机

2 信号类型 

 linux的基本信号类型

操作 常用的信号

        2)SIGINT:中断信号(可以在终端按ctrl + c输入)
        3)SIGQUIT:退出信号(可以在终端按ctrl + \输入)
        9)SIGKILL:杀死信号
        11)SIGSEGV:段错误信号
        13)SIGPIPE:管道破裂信号
        14)SIGALRM:定时信号
        17)SIGCHLD:当前进程有子进程结束(子进程结束,操作系统会给父进程发送SIGCHLD)
        18)SIGCONT:继续执行信号
        19)SIGSTOP:暂停信号
        29)SIGIO:异步IO信号
        20)SIGTSTP:挂起信号(可以在终端按ctrl + z输入)

 

         10) SIGUSR1        专门预留给程序员使用的未定义信号。
         12 )SIGUSR2        专门预留给程序员使用的未定义信号。

3 怎么操作信号

信号发送方

用以下函数实现操作
    kill
    raise
    alarm
    pause
    ...
信号接收方
每个进程都会对信号做出默认响应,但是不是唯一响应。
一般对信号的处理方法有三种:
                1.缺省 
                    按照默认方式处理信号
                2.忽略
                    不处理信号
                3.捕捉
                    按照自定义方式处理信号
特殊的:9)SIGKILL和19)SIGSTOP        不能被忽略和捕捉 

signal

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

功能:

注册一个信号并设置信号的处理方式
参数:
signum:信号的编号
handler:信号的处理方式  捕获
SIG_IGN  忽略
SIG_DFL  缺省
信号对应的处理函数地址
返回值:
成功返回上一次注册的信号处理函数
失败返回SIG_ERR 

 kill

int kill(pid_t pid, int sig);

功能:
给进程发送信号
参数:
pid:进程的ID号
sig:信号的Id
返回值:
成功返回0
失败返回-1 

raise

int raise(int sig);

功能:
给自己发送一个sig信号
参数:
sig:信号的ID
返回值:
成功返回0
失败返回-1 

alarm

unsigned int alarm(unsigned int seconds);

功能:
过seconds秒后给自己发送一个SIGALRM信号
参数:
seconds:过seconds秒后发送信号 
返回值:
上次定时剩余的时间

比如:alarm(0);

关闭定时 

 pause

int pause(void);

功能:
让调用pause的进程或线程挂起
参数:

缺省void
返回值:
失败返回-1  

注意

注意:
1.pause挂起后,收到信号才能被唤醒
2.信号不能按默认方式处理,否则进程任务会结束,应该改为捕捉信号 

范例1(自己用信号发送书写sleep函数实现定时炸弹) 

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <semaphore.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>

void handle(int arg)
{
     
}
int Mysleep(int n)
{
     signal(SIGALRM, handle);
     int i = alarm(n);
     pause();
     return 0;
}
int main(int argc, char const *argv[])
{
     int i = 10;
     while(i--)
     {
          printf("炸弹%d秒后爆炸\n",i);
          Mysleep(1);
     }
     printf("爆炸\n");
     return 0;
}

 一秒打印一句

 范例2(用信号发送书写功能检测用户是否输入,如果用户3s内没有输入,则超时一次,如果超时3次则自动退出。)

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <semaphore.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int times = 3;
void handle(int arg)
{    
     if(0 == times)
     {
          exit(0);
     }
     else
     {
          times--;
          printf("你还有%d次输入机会\n",times);
          alarm(3);
     }
}
int main(int argc, char const *argv[])
{
     char tmp[1024] = {0};
     signal(SIGALRM,handle);

     while (1)
     {
          alarm(3);
          fgets(tmp,sizeof(tmp),stdin);
          times = 3;
     }
     return 0;
}

 运行结果可以看到,我只要三秒不输入就会扣除一次输入机会,倘若输入了,就会重新又三次机会,如果三次机会后都没有输入就会退出程序。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨CX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值