Linu系统编程---9(SIGCHLD 信号,信号传参,中断系统调用)

SIGCHLD 信号

SIGCHLD 的产生条件

  1. 子进程终止时
  2. 子进程接收到 SIGSTOP 信号停止时
  3. 子进程处在停止态,接受到 SIGCONT 后唤醒时

借助 SIGCHLD 信号回收子进程

子进程结束运行,其父进程会收到 SIGCHLD 信号。该信号的默认处理动作是忽略。可以捕捉该信号,在捕捉函 数中完成子进程状态的回收。

linux系统根据未决信号集来处理信号,多个信号进入未决信号集只处理一次。

#include<stdio.h>                                                                    
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h>//出错处理函数
void sys_err(char * str)
{perror(str);exit(1);
}void do_sig_child(int signo)
{int status;//传出参数pid_t pid;//进程ID//status子进程退出状态while((pid = waitpid(0,&status,WNOHANG))>0){if(WIFEXITED(status))printf("--------child %d exit %d\n",pid,WEXITSTATUS(status));else if(WIFSIGNALED(status))printf("child %d cancel signal %d\n",pid,WTERMSIG(status));}   
}int main(void)
{pid_t pid;int i;//阻塞SIGCHLDfor(i=0;i<10;i++){if((pid = fork()) == 0){ break;}else if(pid<0){sys_err("fork");}}if(pid == 0){int n=1;while(n--){printf("child ID %d\n",getpid());sleep(1);}return i+1;}else if(pid >0 ){//有可能再注册信号过程中子进程死亡,所以要先对SIGCHILD信号进程阻塞//SIGCHILD阻塞struct sigaction act;act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD,&act,NULL);//解除对SIGCHLD的阻塞while(1){printf("Parent ID %d\n",getpid());sleep(1);}}return 0;
}          

在这里插入图片描述

子进程结束 status 处理方式

pid_t	waitpid(pid_t		pid,int*	status,int	options) 
  1. options
    WNOHANG
    没有子进程结束,立即返回
    WUNTRACED
    如果子进程由于被停止产生的 SIGCHLD,waitpid 则立即返回
    WCONTINUED
    如果子进程由于被 SIGCONT 唤醒而产生的 SIGCHLD,waitpid 则立即返回
  2. 获取 status
    WIFEXITED(status)
    子进程正常 exit 终止,返回真
    WEXITSTATUS(status)返回子进程正常退出值
    WIFSIGNALED(status)
    子进程被信号终止,返回真
    WTERMSIG(status)
    返回终止子进程的信号值
    WIFSTOPPED(status) 子进程被停止,返回真
    WSTOPSIG(status)返回停止子进程的信号值 WIFCONTINUED(status)

SIGCHLD 注意

  1. 子进程继承了父进程的信号屏蔽字和信号处理动作,但子进程没有继承未决信号集 spending。
  2. 注意注册信号捕捉函数的位置。
  3. 应该在 fork 之前,阻塞 SIGCHLD 信号。注册完捕捉函数后解除阻塞。

信号传参

发送信号传参

sigqueue 函数对应 kill 函数,但可在向指定进程发送信号的同时携带参数 int sigqueue(pid_t pid,int sig,const union sigvalvalue);成功:0;失败:-1,设置

errno union	sigval
{ int sival_int;void*sival_ptr;//这个地址给本进程使用
};

向指定进程发送指定信号的同时,携带数据。但,如传地址,需注意,不同进程之间虚拟地址空间各自独立, 将当前进程地址传递给另一进程没有实际意义。

捕捉函数传参

int	sigaction	(int	signum,const	struct	sigaction*act,struct	sigaction*oldact);structsigaction{ void       (*sa_handler)(int); void  	 (*sa_sigaction)(int,siginfo_t*,void*); sigset_t 	sa_mask;int 	sa_flags; void 	(*sa_restorer)(void);}; 

当注册信号捕捉函数,希望获取更多信号相关信息,不应使用 sa_handler 而应该使用 sa_sigaction。但此时的 sa_flags 必须指定为 SA_SIGINFO。siginfo_t 是一个成员十分丰富的结构体类型,可以携带各种与信号相关的数据。

中断系统调用

系统调用可分为两类:慢速系统调用其他系统调用。

慢速系统调用:

可能会使进程永远阻塞的一类。如果在阻塞期间收到一个信号,该系统调用就被中断,不再 继续执行(早期);也可以设定系统调用是否重启。如,read、write、pause、wait…

其他系统调用:

getpid、getppid、fork…

结合 pause,
回顾慢速系统调用:
慢速系统调用被中断的相关行为,实际上就是 pause 的行为:
如,read

  1. 想中断 pause,信号不能被屏蔽。
  2. 信号的处理方式必须是捕捉 (默认、忽略都不可以)
  3. 中断后返回-1,
    设置 errno 为 EINTR(表“被信号中断”) 可修改 sa_flags 参数来设置被信号中断后系统调用是否重启。SA_INTERRURT 不重启。 SA_RESTART 重启。

sa_flags 还有很多可选参数,适用于不同情况。如:捕捉到信号后,在执行捕捉函数期间,不希望自动阻塞该 信号,可将 sa_flags 设置为 SA_NODEFER,除非 sa_mask 中包含该信号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383231.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linu系统编程---10(Linux的终端,线路规程,网络终端,进程组)

终端 输入输出设备的总称 在 UNIX 系统中&#xff0c;用户通过终端登录系统后得到一个 Shell 进程&#xff0c;这个终端成为 Shell 进程的控制终端&#xff08;Controlling Terminal&#xff09;&#xff0c; 进程中&#xff0c;控制终端是保存在 PCB 中的信息&#xff0c;而 …

PCRE函数简介和使用示例

PCRE是一个NFA正则引擎&#xff0c;不然不能提供完全与Perl一致的正则语法功能。但它同时也实现了DFA&#xff0c;只是满足数学意义上的正则。 PCRE提供了19个接口函数&#xff0c;为了简单介绍&#xff0c;使用PCRE内带的测试程序(pcretest.c)示例用法。 1. pcre_compile 原型…

Linux系统编程---11(会话,守护进程,创建守护进程)

会话 创建会话 创建一个会话需要注意以下6点注意事项 调用进程不能是进程组组长&#xff0c;该进程变成新会话首进程该进程成为一个新进程组的组长进程需要root权限&#xff08;nbuntu不需要&#xff09;新会话丢弃原有的控制终端&#xff0c;该会话没有控制终端该调用进程是…

判断一段文件是UTF-8编码还是GB2312的编码方式

分类&#xff1a; 算法 cpp2012-03-10 16:01 7120人阅读 评论(2) 收藏 举报null生活c对于只包含中文和英文的文本中判断编码方式是非常简单的&#xff0c;中文的编码方式最常用的是GBK&#xff0c;字符集更大的如GBK向下兼容GB2312&#xff0c;其中包含的的很多一部分字符是我们…

判断文件的编码方式

/*功能&#xff1a;实现文件编码格式的判断通过一个文件的最前面三个字节&#xff0c;可以判断出该的编码类型&#xff1a;ANSI&#xff1a;        无格式定义&#xff1b;(第一个字节开始就是文件内容)Unicode&#xff1a;       前两个字节为FFFE&#xff1b;…

Linux系统编程----12(线程概念,Linux线程实现原理,栈中ebp指针和ebp指针,线程的优缺点和共享资源)

线程概念 什么是线程 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列” 一切进程至少都有一个执行线程线程在进程内部运行&#xff0c;本质是在进程地址空间内运行在Linux系统中&#xff0…

Linux系统编程---13(线程控制函数,创建线程,循环创建多个线程,线程间共享全局变量)

线程控制 操作系统并没有提供创建线程的系统调用接口&#xff0c;因此大佬们封装了一个线程的接口库实现线程控制。意为着用户创建线程都使用的是库函数&#xff08;所以有时候我们说创建的线程是一个用户态线程&#xff0c;但是在内核中对应有一个轻量级进程实现线程程序的调…

Linux系统编程---14(回收子线程,回收多个子线程,线程分离,杀死线程)

回收子线程 pthread_join 函数 阻塞等待线程退出&#xff0c;获取线程退出状态 其作用&#xff0c;对应进程中 waitpid() 函数。 int pthread_join (pthread_t thread,void** retval); 成功&#xff1a;0&#xff0c;失败&#xff1a;错误号 参数&#xff1a;thread&#x…

Linux系统编程----15(线程与进程函数之间的对比,线程属性及其函数,线程属性控制流程,线程使用注意事项,线程库)

对比 进程 线程 fork pthread_create exit (10) pthread_exit &#xff08;void *&#xff09; wait (int *) pthread_join &#xff08;&#xff0c;void **&#xff09;阻塞 kill pthread_cancel ();必须到取消点&#xff08;检查点&#xff09;&#xff1a;…

内核双向循环链表

#include <string.h>#include <stdio.h>#include <stdlib.h>#include<malloc.h>#include <arpa/inet.h>//链表头结构struct list_head{struct list_head *next,*prev;};//真正实现链表插入操作void _list_add(struct list_head *nnew,struct lis…

Linux系统编程----16(线程同步,互斥量 mutex,互斥锁的相关函数,死锁,读写锁)

同步概念 所谓同步&#xff0c;即同时起步&#xff0c;协调一致。不同的对象&#xff0c;对“同步”的理解方式略有不同。如&#xff0c;设备同步&#xff0c;是指在两 个设备之间规定一个共同的时间参考&#xff1b;数据库同步&#xff0c;是指让两个或多个数据库内容保持一致…

转移字符的转换

使得网页上不会显示 \x0a\x0a \x0a \x0a \x0a \x0a 类似的字符static int te_escape_isDec(char *ptr, unsigned int len) { …

Linux系统编程---17(条件变量及其函数,生产者消费者条件变量模型,生产者与消费者模型(线程安全队列),条件变量优点,信号量及其主要函数,信号量与条件变量的区别,)

条件变量 条件变量本身不是锁&#xff01;但它也可以造成线程阻塞。通常与互斥锁配合使用。给多线程提供一个会合的场所。 主要应用函数&#xff1a; pthread_cond_init 函数pthread_cond_destroy 函数pthread_cond_wait 函数pthread_cond_timedwait 函数pthread_cond_signa…

好友

http://blog.csdn.net/liangyuannao/article/details/8583139

Linux系统编程---18(线程池相关概念及其实现)

线程池 概念&#xff1a; 一堆线程任务队列 作用 避免大量线程频繁的创建/销毁时间成本避免瞬间大量线程创建耗尽资源&#xff0c;程序崩溃危险 实现 创建固定数量的线程创建一个线程安全的任务队列 一种线程使用模式。 线程过多会带来调度开销&#xff0c;进而影响缓…

设计模式--1(设计模式基础,设计模式基本原则,设计模式分类)

设计模式基础 模式 在一定环境中解决某一问题的方案&#xff0c;包括三个基本元素–问题&#xff0c;解决方案和环境。大白话&#xff1a;在一定环境下&#xff0c;用固定套路解决问题。 设计模式 是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使…

source insight 使用技巧

source insight 使用技巧 1 sourceinsight screen font 的默认字体是Verdana的&#xff0c;它是一直变宽字体。在Document style中可以将字体改为定宽的Courier2 document options->auto indent 去掉indent Open Brace和Indent Close Brace的效果: 继上一段&#xff0c;在…

设计模式----2(简单工厂模式的概念,简单工厂模式的实现,简单工厂模式的优缺点)

简单工厂模式 简单工厂模式的概念 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负 责创建其他类的实例&#xff0c;被创建的实例通常都具有共同的父类。 具体分类 工厂&#xff08;Creator&#xff09;角色 简单工厂模式的核心&#xff0…

Redis常见问题及其一些重点知识总结

1、什么是 Redis&#xff1f;简述它的优缺点&#xff1f; Redis 的全称是&#xff1a;Remote Dictionary.Server&#xff0c;本质上是一个 Key-Value 类型的内存数据库&#xff0c;很像 memcached&#xff0c;整个数据库统统加载在内存当中进行操作&#xff0c;定期通过异步操…

shell生成随机文件名

1 #!/bin/bash 2 # tempfile-name.sh: 临时文件名产生器 3 4 BASE_STRmcookie # 32-字符的 magic cookie. 5 POS11 # 字符串中随便的一个位置. 6 LEN5 # 取得 $LEN 长度连续的字符串. 7 8 prefixtemp # 最终的一个临时文…