当前位置: 首页 > news >正文

装修公司做网站好做吗企业网站设置

装修公司做网站好做吗,企业网站设置,网站更换内容,域名及密码登录域名管理网站信号也是IPC中的一种,是和管道,消息队列,共享内存并列的概念。 本文参考: Linux中的信号_linux中信号_wolf鬼刀的博客-CSDN博客 Linux系统编程(信号处理 sigacation函数和sigqueue函数 )_花落已飘的博客-CSDN博客 Linu…

信号也是IPC中的一种,是和管道,消息队列,共享内存并列的概念。

本文参考:

Linux中的信号_linux中信号_wolf鬼刀的博客-CSDN博客

Linux系统编程(信号处理 sigacation函数和sigqueue函数 )_花落已飘的博客-CSDN博客

Linux的sigqueue函数_linux sigqueue_QtHalcon的博客-CSDN博客

概念

信号是进程之间异步通知的一种方式,属于软中断;

可以使用“kill -l”来查看系统定义的信号列表:

 在这里插入图片描述

所以,当在终端输入“crtl + c”时,其实就是调用了2号SIGINT,使用信号机制停止了一个程序。

  • 从图中可以看到每个信号都有一个编号宏定义的名称,这些宏都可以在signal.h中找到
  • 注意并不是一共有64个信号,自己仔细看,共有62种信号
  • 31号信号之前都是不可靠信号,也是非实时信号
  • 编号34以上的是实时信号,可靠信号,各种信号各自在什么条件下产生什么默认的动作都可以在signal(7)中查看

同时kill命令还可以用来执行命令,例如一个进程的PID号为1234,则可以使用“kill 9 1234”或“kill SIGKILL 1234” 来杀死这个进程

另外,kill不仅可以使用在命令窗口,kill还可以作为一个API

kill函数 : 给一个指定的进程发送一个指定的信号

包含的头文件:

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

函数原型:

int kill(pid_t pid, int sig);

函数参数:

  • pid:进程号
  • sig:信号编号

信号的处理方式

  • 忽略信号(SIGKILL和SIGSTOP无法被忽略
  • 执行给信号的默认动作
  • 提供一个信号处理函数,要求用户在处理该信号时切换到用户态去执行处理函数,即捕捉信号

其中,对于用户来说,信号更多的意义是实现异步操作,也就是捕捉信号,其核心就是编写“信号处理函数”

信号处理的API函数及应用

signal函数

用来自定义信号处理方式

需要包含的库

#include <signal.h>

函数原型

typedef void (*sighandler_t)(int); //一个指向“传入参数是int 返回值是void的函数”,名为“sighandler_t”的指针sighandler_t signal(int signum, sighandler_t handler);

函数参数

  • signum:信号编号
  • handler:函数指针,指向信号处理函数;也可以使用宏,比如使用“SIG_IGN”,则忽略信号

使用举例1

signal1.c:
#include <signal.h>
#include <stdio.h>void sighandler(int sig)
{printf("get signal:%d\n",sig);}int main()
{signal(2,sighandler);while(1);return 0;
}

可见,当捕获了信号2之后,在键盘输入“ctrl + c” 不再会执行默认动作来结束进程,而是被程序捕获,并执行了信号处理函数

那么此时如何退出进程呢?可以使用刚刚提到的kill指令,先搜索pid号然后直接杀死进程

 

使用举例2 

同样,也可以在程序中直接调用kill函数来发送信号

signal2.c:

编写一个C程序实现“向自己发送指定信号”的功能

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>void sighandler(int sig)
{printf("get signal:%d\n",sig);}int main(int argc,char **argv)
{int signum;pid_t pid;signum = atoi(argv[1]); //由于从键盘接收的是字符串,所以要使用“atoi”函数将ASCII码转为整型数pid = getpid();signal(2,sighandler); //为了实现效果,一定要先执行signal,再执行killkill(pid,signum);while(1);return 0;
}

编译运行代码并指定第二个参数为2: 

 

可见,虽然此时没有在键盘打出 “ctrl + c”,但是内部的代码调用了kill对自己发送了2号信号,所以同样实现了刚刚的效果。

学到了这里,一定会产生疑问:为什么信号会作为IPC中的一员,如果只是发送信号的话,不应该算是一种很有效的进程通讯方式,所以信号的处理还有更高级的方法,也就是带消息的高级信号操作,既然要带消息,那么就需要使用更高级的API函数来实现收发:

  • 发送信号:使用sigqueue函数
  • 接收信号:使用sigaction函数

sigaction函数

实现带消息的高级信号操作,可以接收带消息的信号

需要包含的库

#include <signal.h>

函数原型

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

函数参数

  • signum:信号编号
  • act:指定新的信号处理方式
  • oldact:输出先前信号的处理方式(如果不为NULL的话)

struct sigaction结构体介绍(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:此参数和signal()的参数handler相同,代表新的信号处理函数,如果使用这个成员参数,那就和signal函数无异了
  • sa_sigaction:带消息的信号处理函数

int:第一个参数是信号编号

siginfo_t *:第二个参数是一个结构体,包括si_signo,si_code,si_int,si_value等等各种成员,其中si_signo和si_code必须实现

void *:第三个参数是一个指针,用来指示是否有消息存在,如果为NULL则无消息,否则就有消息

  • sa_mask:用来设置在处理该信号时暂时将sa_mask 指定的信号集搁置,可以理解为处理信号的时候释放阻塞(默认阻塞)
  • sa_flags:用来设置信号处理的其他相关操作,可以是以下值的“按位或”组合:

 ◆ SA_RESTART:使被信号打断的系统调用自动重新发起
 ◆ SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号
 ◆ SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程
 ◆ SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号
 ◆ SA_RESETHAND:信号处理之后重新设置为默认的处理方式
 ◆ SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数(重要

  • re_restorer:是一个已经废弃的数据域,不使用 

sigqueue函数

发送带消息的信号

成功使用sigqueue这个函数需要有两个前提:

  • sigaction函数的第二个参数结构体中的sa_flags成员必须有“SA_SIGINFO
  • sigaction函数的第二个参数结构体中实现的是成员sa_sigaction函数而不是成员sa_handler函数

需要包含的库

#include <signal.h>

函数原型

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

函数参数 

  • pid:目标进程的进程号
  • sig:要发送的信号的编号
  • value:要附带发送的消息

value的类型是一个名为sigval的联合体,如果需要附带的消息是整型,则将数据存入成员“sival_int”;而如果消息类型是字符串,则存入成员“sival_ptr"

union sigval {int   sival_int;void *sival_ptr;
};

使用sigaction和sigqueue的实操演示

需求:编写两个C程序,一个使用sigaction来接收,一个使用sigqueue来发送,实现带消息的信号的通讯

signal3.c:(接收带消息的信号)

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>void sighandler(int sig, siginfo_t *info, void *context)
{printf("get signal:%d\n",sig);if(context != NULL){printf("get data = %d\n",info->si_int);//printf"(get data = %d\n",info->si_value.sival_int);}}int main()
{struct sigaction act;act.sa_sigaction = sighandler;act.sa_flags = SA_SIGINFO;sigaction(2,&act,NULL);while(1);return 0;
}

signal4.c:(发送带消息的信号)

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc,char **argv)
{int signum;pid_t pid;int data;pid = atoi(argv[1]);signum = atoi(argv[2]);data = atoi(argv[3]);union sigval value;value.sival_int = data;	sigqueue(pid,signum,value);printf("signal no.%d has been sent to pid %d, context:%d\n",signum,pid,data);return 0;
}

实现效果:

 首先编译并运行signal3.c

可见,此时没有接收到任何信号,一直阻塞

此时新开一个窗口先查询到这个signal3.c的进程号

然后根据进程号,编译并运行signal4.c,将编号为2的信号发送到signal3.c对应的进程,并附带55的整型消息

此时再回看signal3.c的运行界面 

 

可见,此时不仅收到了来自signal4.c的信号,还收到了附带的整型数据消息 

http://www.sczhlp.com/news/130007/

相关文章:

  • 交换机可以做网站跳转吗工业风 网站建设
  • 湖南省住房和城乡建设厅门户网站营口网站seo
  • 建站总结报告南山网站开发
  • 自建wap网站公司网站备案网站名称有什么用
  • 西宁做网站的公司专门做特卖的网站是什么
  • 做名片哪个网站可以找欧宇公司网络建设方案
  • 网络公司除了建网站自己搞网站建设
  • 黄埔做网站的公司通过服务推广网站
  • 单位网站建设情况芜湖今天刚刚发生的新闻
  • 下载的网站模板如何安装wordpress 输入框
  • vite静态资源处理
  • 洛谷B4040 [GESP202409 四级] 黑白方块 题解
  • SerpApi:一站式搜索引擎数据抓取API完全指南
  • 不成立公司怎么做企业网站产品类网站
  • 茂名网站制作价格门户网站免费建设
  • 江苏省住房和城市建设厅网站公司静态网站模板下载
  • 有哪些做兼职的网站学习网站建设最简单的书
  • 只做公司网站方案WordPress管理员登录不了
  • 博客网站模版手机网站建设+上海
  • 网站建设开发费怎么做账seo课程培训
  • 怎么填写网站备案申请wordpress数据库分析
  • 网站开发设计师薪资个人淘客网站备案
  • 教育行业网站建设价格wp上的wordpress
  • 南宁手机网站制作公司马克杯网站开发
  • 定制网站开发多少钱无做弊的棋牌游戏网站
  • css 使用记录 随笔
  • 大学培训中心网站建设网站建设实训课
  • 建e优化推广网站推荐
  • 织梦网站地图怎么做产品经理培训哪个机构好
  • asp.net做网站Dreamver最简单仓库管理软件