信号-signal 的基本概念

1. 信号(signal)机制是Unix系统中最为古老的进程间通信机制。
很多条件可以产生一个信号:
a. 当用户按下某些按键时,可以产生信号。
b. 硬件异常产生信号:如除数为0,无效的存储访问等等。
这些情况通常由硬件检测到,将其通知内核。然后内核产生适当的信号通知进程。
例如:内核对正在访问一个无效存储区的进程产生一个SIGSEGV信号。
c. 进程用 kill函数 将信号发送给另一个进程
d. 用户可以用 kill命令 将信号发送给其他进程。


2. 信号类型:

常见的信号:
SIGHUP --- 从终端上发出的结束信号
SIGINT --- 来自键盘的中断信号(ctrl + c)
SIGKILL --- 该信号结束接收信号的进程
SIGTERM --- kill 命令发出的信号
SIGCHLD --- 标识子进程停止 或结束的的信号

SIGSTOP --- 来自键盘(ctrl + z)或调试程序的执行信号。

其他信号还有一些。


3. 信号处理

当某信号出现时,会按照下面三种方式进行处理:
a. 忽略此信号
大多数信号都按照这种方式进行处理,但有两种信号决不能被忽略:SIGKILL 和 SIGSTOP。
这两种信号不能被忽略的原因是:他们向超级用户提供了一种终止会停止进程的方法。
b.执行用户希望的动作
通知内核在某种信号发生时,调用一个用户函数,在用户函数中,执行用户希望的处理
c. 执行系统默认动作
对大多数信号的系统默认动作是终止该进程。


4. 信号发送

发送信号的主要函数有 kill 和 raise。
kill 和 raise 的区别:
kill既可以向自身发送信号,也可以向其他进程发送信号。
raise只能向自身进程发送信号。
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);


5. Alarm 也可以发送信号

使用alarm函数可以设置一个时间值(闹钟时间),当锁设置的时间到了,产生SIGALRM信号。
如果不捕捉此信号,则默认动作时终止该进程。

#include <unistd.h>
unsigned int alarm(unsigned int seconds)
seconds --- 经过了指定的 seconds秒 后,会产生信号SIGALRM。
每个进程只能有一个闹钟。
如果在调用alarm时,以前已为该进程设置过闹钟时间,而且它还没有超时,则以前登记的闹钟时间会被新值替换。
如果以前有登记的尚未超时的闹钟时间,而这次seconds值是0,则表示取消以前的闹钟。


6. pause --- 进程等待

pause 函数 使调用进程挂起,直到捕捉到一个信号。
#include <unistd.h>
int pause(void);
只有执行了一个信号处理函数后,挂起才结束。
pause和wait的区别
wait() --- 等待子进程退出为止。
pause() --- 等到进程收到一个信号为止。


7. 信号处理

信号处理的主要方式有2种:
a. 使用简单的signal 函数
b. 使用信号集函数组。


8. signal() 函数  --- 建立 某信号和接受到某信号后的处理函数机制


#include <signal.h>
void (*signal(int signo, void (*func)(int)))(int)
也被定义为:
typedef void(*sighandler_t)(int)  ---函数指针
sighander_t signal(int signum, sighandler_t handler)
signo --- 指定某一信号。

*func --- 接受到该信号后,要执行的处理函数

func可能的值
a. SIG_IGN: 忽略此信号
b. SIG_DFL: 按系统默认方式处理
c. 信号处理函数名: 使用该函数处理
例: mysignal.c

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void my_func(int sign_no)
{
        if(sign_no == SIGINT)
                printf("I have get SIGINT\n");
        else if(sign_no == SIGQUIT)
                printf("I have get SIGQUIT\n");
}

int main()
{
        printf("Waiting for signal SIGINT or SIGQUIT\n");

        //注册信号处理函数
        signal(SIGINT, my_func);
        signal(SIGQUIT, my_func);

        pause(); //等待信号,收到信号才会结束等待
        exit(0);
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值