今天继续学习信号相关的知识,主要还是学习sigqueue另外信号发送函数,并配合上节学习的sigaction的用法,进入正题:

sigqueue函数:
sigval联合体:
实际上sigval参数是用来进程间通信用的,实际上信号是一个很古老的进程间通信的一种手段,通过这个参数,可以从一个进程发送到另外一个进程,并且可以附带参数。下面以实际代码来说明sigqueue是如何传递数据的:
这里需要编写一个进程发送信号和一个进程接收信号来说明sigqueue:
接收信号:
要想接收信号数据,则需要在sigaction上加入flag,也就是上节当中遗漏的一个知识点,查看man帮助:
 
 
另外,还得注意,如果要想接收信号,需要用到sigaction的另外一个处理函数:
 
具体接收代码如下sigaction_recv.c:
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h> #include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while() void handler(int, siginfo_t *, void *);//需要用带多个参数的handler int main(int argc, char *argv[])
{
struct sigaction act;
act.sa_sigaction = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;//设置该flags可以接收其它进程传过来的信号 if (sigaction(SIGINT, &act, NULL) < )
ERR_EXIT("sigaction error"); for (;;)
pause();
return ;
} void handler(int sig, siginfo_t *info, void *ctx)
{
printf("recv a sig=%d data=%d\n", sig, info->si_value.sival_int);//它实际上就是sigqueue的sigval联合体,并打印出传过来的整型值
}
 
发送信号:
编写一个通过sigqueue向某进程发送信号并携带数据来达到进程间通讯的目的:
sigaction_send.c:
编译运行:
先运行接收信号的程序:
再运行进程发送程序,向该接收进程发送信号,先找到该接收进程号:
然后进行我们写的信号发送程序:
另外,数据的接收还可以用这种方式来打印:
输出如下:
为啥可以这样写呢?查看sigaction的帮助:
所以通过这种方式就能达到进程间通讯的目的。
接下来再演示一个不可靠与可靠信号的一个问题:可靠信号支持排队,不可靠信号是不支持排队的
验证方法:
① 写一个接收程序,里面注册一个可靠信号,一个不可靠信号,并将其加入屏蔽字中进行阻塞,然后再注册一个解除这两个信号阻塞的信号,程序如下:
sigaction_recv.c:
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h> #include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while() void handler(int); int main(int argc, char *argv[])
{
struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = ; sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGRTMIN);
sigprocmask(SIG_BLOCK, &s, NULL);//将这两个信号都加入屏蔽字当中进行阻塞
if (sigaction(SIGINT, &act, NULL) < )//注册一个不可靠信号
ERR_EXIT("sigaction error"); if (sigaction(SIGRTMIN, &act, NULL) < )//注册一个可靠信号
ERR_EXIT("sigaction error"); if (sigaction(SIGUSR1, &act, NULL) < )//注册一个解除阻塞信号的信号
ERR_EXIT("sigaction error");
for (;;)
pause();
return ;
} void handler(int sig)
{
if (sig == SIGINT || sig == SIGRTMIN)
printf("recv a sig=%d\n", sig);
else if (sig == SIGUSR1)
{//当接收到SIGUSR1信号时,则解除阻塞,这时被阻塞的SIGINT,SIGRTMIN信号就变为递达状态了,这时就可以观察两者的区别了
sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGRTMIN);
sigprocmask(SIG_UNBLOCK, &s, NULL);
}
}

② 编写一个发送信号的程序,里面发送多个SIGINT可靠信号,多个SIGTMIN不可靠信号,并且延时几秒之后,再将发送SIGUSR1信号解除绑定,最终观察看SIGINT收到了几个,SIGTMIN收到了几个,具体代码如下:

sigaction_send.c:

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h> #include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while() int main(int argc, char *argv[])
{
if (argc != )
{
fprintf(stderr, "Usage %s pid\n", argv[]);
exit(EXIT_FAILURE);
} pid_t pid = atoi(argv[]);
union sigval v;
v.sival_int = ;
sigqueue(pid, SIGINT, v);
sigqueue(pid, SIGINT, v);
sigqueue(pid, SIGINT, v);//发送三个SIGINT不可靠信号 sigqueue(pid, SIGRTMIN, v);
sigqueue(pid, SIGRTMIN, v);
sigqueue(pid, SIGRTMIN, v);//发送三个SIGTMIN可靠信号 sleep();//休眠3秒,目的是让其多个信号进行阻塞 kill(pid, SIGUSR1);//发送一个SIGUSR1信号进行解除阻塞,改用kill来发送,当然也可用sigqueue啦
return ;
}

编译运行:

从运行结果来看,经过3秒之后,34号信号,也就是SIGRTMIN信号接收了三次,而2号信号SIGINT信号只接收了一次,所以也论证了可靠信号是支持排队的,而不可靠信号是不支持排队的

关于sigaction还有很多其它的用法,这个之后有需求再进行探索,好了,今天的内容就学到这,下节见!

linux系统编程之信号(六)的更多相关文章

  1. linux系统编程之信号(七)

    今天继续学习信号,主要是学习关于时间和定时器相关的函数的使用,关于这个实际上有很多内容,这里先简要进行说明,等之后再慢慢进行相关深入,也主要是为接下来要做的一个综合linux系统编程的例子做准备,好了 ...

  2. linux系统编程之信号(一):中断与信号

    一,什么是中断? 1.中断的基本概念 中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序,待处理完毕后又返回原来被 ...

  3. linux系统编程之信号(二)

    经过了漫长的间歇,对于c语言的学习也被中断了很久,现实确实有很多的无耐,计划中的事情总会被打乱,但不管怎样,学习的道路是不能休止的,所以经过了一断温习后现在继续学习C语言,话不多说,进入正题: 信号分 ...

  4. linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction

    一,sigaction() #include <signal.h> int sigaction(int signum,const struct sigaction *act,struct ...

  5. linux系统编程之信号(七):被信号中断的系统调用和库函数处理方式

        一些IO系统调用执行时, 如 read 等待输入期间, 如果收到一个信号,系统将中断read, 转而执行信号处理函数. 当信号处理返回后, 系统遇到了一个问题: 是重新开始这个系统调用, 还是 ...

  6. linux系统编程之信号(三):信号安装、signal、kill,arise讲解

    一,信号安装 如果进程要处理某一信号,那么就要在进程中安装该信号.安装信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系,即进程将要处理哪个信号:该信号被传递给进程时,将执行何种操作. li ...

  7. linux系统编程之信号(二):信号处理流程(产生、注册、注销、执行)

        对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个阶段: 信号诞生 信号在进程中注册 信号在进程中的注销 信号处理函数执行 1    信号诞生     信号事件 ...

  8. linux系统编程之信号(一)

    今天起,开始新的知识的学习,对于上个系列进程的学习还差一个理论上的总结,这个会下次补回来,以便通过实践之后,再用理论将其巩固一下,好了,话不多说,开始进入这个主题的学习----信号,很重要,但不是太容 ...

  9. linux系统编程之信号(八):三种时间结构及定时器setitimer()详解

    一,三种时间结构 time_t://seconds   struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microsecond ...

随机推荐

  1. [LeetCode] 274. H-Index H指数

    Given an array of citations (each citation is a non-negative integer) of a researcher, write a funct ...

  2. [LeetCode] 502. IPO 上市

    Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Cap ...

  3. jmap使用

    今天写的服务在处理大文件是出现Java heap space错误,因此结识了jmap jmap是JDK自带的一个工具,可以做jvm性能调优 可以生成dump文件,查询finalize执行队列.Java ...

  4. 《十天学会 PHP》的重难点

    记录一下我在学习<十天学会 PHP>(第六版)的过程中的遇到的重难点,该课程是学习制作一个简单的留言板. 准备工作 XAMPP(Apache + MySQL + PHP + PERL) 是 ...

  5. Spring中的乱码问题

    最近发现一个问题, 中文编码保存到数据库里显示正确, 打印出来却是一串问号, 然后怀疑是平台默认编码的问题, locale命令显示是UTF-8正常, 然后单独编写一个java文件, 编译然后Java命 ...

  6. sql server版本特性简介、版本介绍简介

    1.SQL Server 版本简介 1.1.sql server的版本信息 年    代 版    本 大版本号 1993年 SQL Server for Windows NT 4.21 1994年 ...

  7. Django之拾遗

    一.设计模式 1.1 MVC 模型(M)是数据的表述,非真正数据,而是数据接口. 视图(V)是你看到的界面,是模型的表现层,此外还提供了收集用户输入的接口. 控制器(C)控制模型和视图之间的信息流动. ...

  8. Linux安装centos

    在虚拟机上安装centos 虚拟机使用win10自带的hyper-v非常好用 centos下载地址http://mirrors.aliyun.com/centos/7.6.1810/isos/x86_ ...

  9. 小贴士--Python

    1.查看python安装好的包版本信息:pip list 原贴,有空完善.http://yangzb.iteye.com/blog/1824761 2.Python文件快速执行. 加头文件快速执行Py ...

  10. html input复选框的checked属性

    input --checked: 只要复选框有checked属性,不管属性值为空或者为true or false或任意值,复选框都会被选中.切忌:checked属性值不要带引号 <input t ...