我们接着谈Linux学习过程中一个重要的话题--信号。

一、信号的概念:

信号是一种软件中断,它提供了一种处理异步事件的方法,也是进程间唯一的异步通信方式。

二、信号的来源:

1、硬件方式:

当用户按下终端上某些键时,将产生信号。

硬件异常产生信号:除0操作、访问非法空间……

2、软件方式

用户在终端下调用kill命令向进程发送任意信号

进程调用kill或者sigqueue函数发送信号。

当检测到某种软件条件发生时,如alarm或者setimer

三、信号处理

1、信号的捕捉和处理

1、signal函数

a、函数作用:

signal函数用来设置进程在接收到信号时的动作。

b、函数原型:#include

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

c、参数解析与函数说明:

signal函数会根据参数signal指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会

跳到参数hander指定的函数执行。如果hander不是函数指针,则必须时常数SIG_IGN忽略该信号)或者S

IG_DFL(对该信号执行默认操作)。hander是 一个函数指针,它所指向的函数的类型时sighandel_t,即

它 所指向的函数有一个int型参数,且返回值的类型为void。

d、样这里给出signal处理信号的例子:/**********************************************************

*    > File Name: signal-1.c

*    > Author:xiao_k

*    > Mail:18629086235@163.com

*    > Created Time: Fri 23 Feb 2018 12:05:46 AM CST

**********************************************************/

#include

#include

#include

#include

#include

#include

//信号处理函数

void do_sig(int num)

{

printf("I am do_sig\n");

}

int main()

{

//安装处理信号

signal(SIGINT,do_sig);

while(1)

{

printf("********\n");

sleep(1);

}

return 0;

}

2、sigaction函数

a、函数作用:

sigction函数可以用来检查和设置进程在接收信号时的动作。

b、函数原型

#include

int sigaction(int signum, const struct sigaction *act,

struct sigaction *oldact);

c、参数解析与函数说明:

sigzction函数会根据参数signum指定的信号编号来设置该信号的处理函数。参数signum可以是除了

SIGKILLh和SIGSTOP以外的任何信号。

如果参数act 不是空指针,则为signum设置新的信号处理函数;

如果oldzct不是空指针,则旧的信号处理函数将被存储在oldact中,struct sigaction的定义如下:

struct sigaction {

void     (*sa_handler)(int);

void     (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t   sa_mask;

int        sa_flags;

void     (*sa_restorer)(void);

};

sa_handler可以是常数SIG_DFL或者SIG_IGN,或者是一个信号处理函数名。

sa_sigaction也是用来指定信号的signum的处理函数。

sa_mask成员声明了一个信号集,在调用信号捕捉函数之前,该信号会增加到进程的信号屏蔽码中,

新的信号屏蔽码会自动包括正在处理的信号(sa_flags未指定SA_NODEFER或者SA_NOMASK)。当从信号捕

捉函数返回时,进程的信号屏蔽码会恢复为原来的值。因此,当处理一个给定的  信号时,如果这种

信号再次发生,那么它会阻塞直到本次信号处理结束为止。若这种信号发生了多次,则对于不可靠信号,

即本次信号处理结束以后只会再次处理一次(相当于丢失了信号),对于可靠信号(实时信号),则会

被阻塞多次,即信号不会丢失,信号发生了多少次就会调用信号处理函数多少次。

sa_flags成员用来说明信号处理的其他相关操作。

当使用三参数的sa_sigaction来指定信号处理函数时,它的第 二个参数可以用来传递数据,其定义

如下:

siginfo_t {

int      si_signo;    /* Signal number */

int      si_errno;    /* An errno value */

int      si_code;     /* Signal code */

int      si_trapno;   /* Trap number that caused

hardware-generated signal (unused on most architectures) */

pid_t    si_pid;      /* Sending process ID */

uid_t    si_uid;      /* Real user ID of sending process */

int      si_status;   /* Exit value or signal */

clock_t  si_utime;    /* User time consumed */

clock_t  si_stime;    /* System time consumed */

sigval_t si_value;    /* Signal value */

int      si_int;      /* POSIX.1b signal */

void    *si_ptr;      /* POSIX.1b signal */

int      si_overrun;  /* Timer overrun count;POSIX.1b timers */

int      si_timerid;  /* Timer ID; POSIX.1b timers */

void    *si_addr;     /* Memory location which caused fault */

int      si_band;     /* Band event */

int      si_fd;       /* File descriptor */

}

d、同样给出 sigaction的测试用例/**********************************************************

*    > File Name: sigaction-1.c

*    > Author:xiao_k

*    > Mail:18629086235@163.com

*    > Created Time: Fri 23 Feb 2018 01:47:43 AM CST

**********************************************************/

#include

#include

#include

#include

#include

int temp = 0;

//信号处理函数

void do_sigact(int num)

{

printf("recv SIGINT\n");

sleep(5);

temp +=1;

printf("the value of temp is :%d\n",temp);

printf("in do_sigact,after sleep\n");

}

int main()

{

struct sigaction act;

//结构体赋值

act.sa_handler = do_sigact;

act.sa_flags = SA_NOMASK;

//安装信号处理函数

sigaction(SIGINT,&act,NULL);

while(1)

{

printf("********************\n");

sleep(1);

}

return 0;

}

编写信号处理函数时,要注意不要使用不可重入的函数,使用了不重入的函数将将产生不可预料的结果。

上边就是sigaction函数的基本用法,复杂的用法后边使用。

补充:满足下列条件的函数是不可重入的:

a、使用了静态的数据结构,如getgrpid(),全局变量等。

b、函数实现时,调用了malloc()或者free()函数。

c、函数实现时,使用了标准I/O函数。

3、pause()函数

a、函数作用:

pause函数使调用进程挂起直到捕捉到一个信号。pause函数会令目前的进程暂停(进入睡眠状态),

直到被信号(signal)所中断,该函数只返回-1,并将errno设置为EINTR。

b、函数原型:

#include

int pause(void);

四、信号的发送:

信号的发送主要由函数kill、raise、sigqueue、alarm、setitimer以及 abort来完成。

1、kill函数

a、函数作用:

kill函数用来发送信号给指定的进程。

b、函数原型#include

#include

int kill(pid_t pid, int sig);

c、参数解析与函数说明:

该函数的行为与第二个参数pid的取值有关,第二个参数sig表示信号编号:

如果pid时正数,则发送信号sig给进程号为pid的进程;

果pid为0,则发送信号sig给当前进程所属进程组里的所有进程;

如果pid为-1,则把信号sig广播给系统内的除1号进程和自身以外的所有进程;

如果pid为比-1还小的负数,则发送信号sig给属于进程组-pid的所有进程;

如果参数sig是0,则kill(),仍然执行正常的错误检查,但不发送信号。可以利用这一点来确定某

进程是否有权向另外一个进程发送信号。如果向一个并不存在的进程发送空信号,则kill()返回-1,

errno则被设置为ESRCH。

注意:只有具有root权限的进程才能向其他任意一个进程发送信号,非root权限的进程只能向属于同一

个组成或者同一个用户创建的进程发送信号。

2、raise函数

a、函数作用:

raise函数是ANSI C 而非POSIX标准定义的。用来给调用它的进程发送信号。

b、函数原型#include

int raise(int sig);

3、sigqueue函数

a、函数作用

sigqueue函数是一个比较新的发送信号的函数,它支持信号带有参数,从而可以与函数sigaction配

合使用。

b、函数原型

#include

int sigqueue(pid_t pid, int sig, const union sigval value);

c、参数解析与函数说明:

sigqueue用来发送给信号sig给进程pid。与kill系统调用不同的是,sigqueue在发送信号的同时

还支持信号携带参数;另外一个不同点是sigqueue 不能给一组进程发送信号,参数value是一个共用

体,其定义如下:

union sigval {

int   sival_int;

void *sival_ptr;

};

4、alarm函数

a、函数作用

alarm函数可以用来设置定时器,定时器超时将产生SIGALRM信号给调用进程。

b、函数原型#include

unsigned int alarm(unsigned int seconds);

c、参数解析与函数说明:

参数seconds表示设定的秒数,经过seconds后,内核将给调用该函数的进程发送SIGALRM信号。如果seconds为0,

则不再发送SIGALRM信号,最新一次调用alarm函数将取消之前一次的设定。

5、abrot函数

a、函数作用:

abrot函数用来向进程发送SIGABRT信号。

b、函数原型#include

void abort(void)

上边我只对信号的基本用法做了总结,后边将对信号的高级用法做单独总结。

linux 进程间广播,Linux系统编程之进程间通信之浅谈信号相关推荐

  1. linux 进程间切换,linux 进程管理 进程切换

    2.Arm体系架构中进程切换过程 在之后的文章里,可能会有很大部分的篇幅是介绍内核如何调度和管理进程.学习了解这部分内容,很多时候是和task struct,run queue,schedule en ...

  2. linux进程间信号量

    linux进程间信号量 Linux 提供的各种系统调用来实现一个具有两种状态的信号量(binary semaphore). 分配和释放 和用于分配.释放共享内存的 shmget 和 shmctl 类似 ...

  3. (大集合)Linux进程和线程的基本编程、通讯和例程【杂记】

    Linux 进程 和 线程 的基本 编程.通讯 和 例程 注:[杂记]系列为日常网搜资料的堆砌而积累成之.如有错误恭谢指出.标识为"原创"其实不完全是,只是多引用再整理和加上自己的 ...

  4. 深刻理解 Linux 进程间七大通信(IPC)

    前言 网络编程是 Linux C/C++的面试重点,今天我就来聊一聊进程间通信的问题,文章末尾列出了参考资料,希望帮助到大家. 篇幅有点长,希望大家耐心阅读. Linux 下的进程通信手段基本上是从 ...

  5. 【Linux系统编程】进程间通信之无名管道

    00. 目录 文章目录 00. 目录 01. 管道概述 02. 管道创建函数 03. 管道的特性 04. 管道设置非阻塞 05. 附录 01. 管道概述 管道也叫无名管道,它是是 UNIX 系统 IP ...

  6. 【Linux系统编程】进程间通信概述

    00. 目录 文章目录 00. 目录 01. 进程间通信概述 02. 进程间通信目的 03. 进程间通信机制 04. 附录 01. 进程间通信概述 进程是一个独立的资源分配单元,不同进程(这里所说的进 ...

  7. linux共享内存示例,linux 进程间共享内存示例

    写入端: #include #include #include #include #include using namespace std; struct MappingDataType { int ...

  8. msgget();msgsnd();msgrcv();msgctl(); 消息队列 Linux进程间的通信方式之消息队列

    Linux进程间的通信方式 ----消息队列. 消息队列和共享内存类似 消息队列它允许一个或多个进程向它写消息,一个或多个进程向它写读消息. 消息队列存在于系统内核中,消息的数量受系统限制. 我们来看 ...

  9. Linux 进程间通讯(IPC)方式 ------- 共享内存

    Linux 进程间通讯(IPC)方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) ...

最新文章

  1. 喜报!清华社《晓肚知肠:肠菌的小心思》荣获“2018年度中国好书”奖
  2. 零基础python从入门到精通 pdf-跟老齐学Python:从入门到精通PDF电子版
  3. 数据库迁移之从oracle 到 MySQL
  4. Linux Kernel中spinlock的设计与实现
  5. nginx,tomcat,apache三者分别用来做什么,有何区别
  6. Petya and Exam
  7. C语言字符串分离数字和字母,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
  8. NSURLErrorDomain 对照
  9. 四叶草黑苹果启动器:Clover EFI bootloader for Mac
  10. Qt信号与槽机制原理
  11. ld.exe: cannot find -l?eclipse上用C/C++时,如何链接静态库?
  12. 前端程序员兼职副业平台推荐
  13. 矩阵方程的计算求解(Matlab实现)
  14. 从零到一学习计算机视觉:朋友圈爆款背后的计算机视觉技术与应用 | 公开课笔记...
  15. android禁止输入框自动弹出软键盘,怎么禁用输入法-Android禁止EditText输入框自动弹出软键盘的4种方法...
  16. 区块链三加一:200个ETH在imToken上怎么没的?
  17. 智慧运维解决方案-最新全套文件
  18. 2013年Devoxx法国-第3天
  19. L1正则化、L2正则化的多角度分析和概率角度的解释
  20. 2021软件测试面试题汇总【备战金九银十】内容较长建议收藏

热门文章

  1. LED显示驱动(二):显示驱动FPGA验证流程与注意细节
  2. excel删除行 uipath_工作再忙,也要学会这10个最经典的Excel小技巧
  3. 根据一个id查找出数组里面的数据并改掉_Excel最强大的VLOOKUP以及INDEXamp;MATCH查找函数...
  4. python torchvision_pip install torchvision error:安装版本为0.4.1的torch后继续安装torchvision报错...
  5. 服务器压力测试_性能测试相关的面试题
  6. mysql 字符串用省略号_CSS截取字符串自动补充省略号
  7. c 连接mysql数据库_C++连接mysql数据库的两种方法
  8. T计算机硬件系统是指,计算机硬件系统试题 有答案
  9. matlab泛函分析,Matlab数字图像处理的学习建议 – MATLAB中文论坛
  10. emq与mysql_EMQ X 插件持久化系列 (五)MySQL MQTT 数据存储