• 进程间通信IPC-信号


    信号

    信号是进程间通信的一种方式 这种方式并没有传输数据 只是在内核中传了一个信号(整数)
    信号的表示是一个整数
    不同的信号值 代表不同的含义 当然用户可以自定义信号

    信号的本质其实是软中断
    信号会中断正在进行的程序 转而去处理中断(处理函数)
    处理完中断后 再回来继续执行原有的程序
    注意:如果用户没有显式地处理信号 系统收到信号默认地处理方式大多是终止进程

    查看信号可以在终端上输入

    man 7 signal 
    
    • 1

    几个常用的信号:

    
    	
    		Signal     Value     Action   Comment
           ──────────────────────────────────────────────────────────────────────
           
           SIGINT        2       Term    Interrupt from keyboard 
    									 从键盘上收到了中断信号 按下ctrl+c就会产生这个信号 
    									 
           SIGQUIT       3       Core    Quit from keyboard
    								     默认的处理是输出信息然后终止进程 按下ctrl+\就会产生这个信号
    									 
         
           SIGFPE        8       Core    Floating-point exception
    									 浮点数运算异常的时候 产生SIGFPE信号 
    									 
           SIGKILL       9       Term    Kill signal  
    									 杀死进程 不可被捕获和忽略
    	   SIGSTOP   17,19,23    Stop    Stop process	
    									 停止进程 不可被捕获和忽略 
    									 
           SIGSEGV      11       Core    Invalid memory reference
    									 非法内存引用时 就会收到SIGSEGV信号 
    									 比如段错误 一旦产生段错误 进程收到SIGSEGV信号 此时输出信号 
    									 然后终止进程
    	   
           SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                         readers; see pipe(7)
    									 当你往一个管道写数据时 没有读端进程就会产生SIGPIPE信号
    									 
           SIGALRM      14       Term    Timer signal from alarm(2)
    									 定时信号 在进程调用alarm时 会在超时的时候 就会产生SIGALRM信号
    	         
           SIGUSR1   30,10,16    Term    User-defined signal 1
           SIGUSR2   31,12,17    Term    User-defined signal 2
    	   
           SIGCHLD   20,17,18    Ign     Child stopped or terminated
    									 当子进程停止或终止的时候 父进程就会收到该信号 
    									 父进程收到这个信号并不会怎么样 因此信号的默认行为是忽略
          
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    linux下信号相关的API函数
    1.发送信号kill

    NAME
    			   kill - send signal to a process
    
    		SYNOPSIS
    			   #include 
    			   #include 
    
    			   int kill(pid_t pid, int sig);
    
    			函数功能: kill用来把一个信号发送到一个指定的进程或多个进程 
    					   kill不仅仅是一个函数 也是一条指令
    					   
    			头文件:如上 
    			
    			参数列表: 
    					pid : 指定信号的接收者(可能是多个进程 )
    						
    						pid > 0  pid表示指定的那一个要发送的进程
    						
    						pid = 0  发送信号给 与调用进程同组的所有进程 
    						
    						pid = -1 发送信号给系统所有进程(有权限发送的所有进程)
    						
    						pid < -1 发送信号给组id等于pid绝对值的所有进程 
    						
    					sig: 你要发送的信号  参考上面的宏
    						
    			返回值: 
    					成功(至少有一个进程成功接收到信号)返回0 
    					失败返回-1 并且errno被设置
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    1. raise
    NAME
    				   raise - send a signal to the caller
    
    			SYNOPSIS
    				   #include 
    
    				   int raise(int sig);
    
    			
    			函数功能: 发送一个信号给自己 
    			
    					
    				raise(sig)==kill( getpid(), sig)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. alarm
    NAME
    				   alarm - set an alarm clock for delivery of a signal
    													
    			SYNOPSIS
    				   #include 
    
    				   unsigned int alarm(unsigned int seconds);
    
    				函数功能: alarm定时发送一个闹钟(SIGALRM)信号给本进程
    						
    						"闹钟":每个进程都有属于自己的一个“闹钟” “闹钟”时间到了 进程就会收到 
    								一个SIGALRM信号 但是同一时刻只有一个“闹钟”生效 
    								
    				头文件:如上 
    				
    				参数列表: 
    						
    						seconds: 多少秒后 发送一个“闹钟信号”
    								  如果为0 代表取消上一个“闹钟”
    								  
    				返回值: 
    						返回上一个闹钟的剩余秒数 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4.捕捉信号 改变信号地处理方式

    NAME
    				   signal - ANSI C signal handling
    
    			SYNOPSIS
    				   #include 
    
    				   typedef void (*sighandler_t)(int);
    				   
    					sighandler_t是一个函数指针类型 它可以用来定义函数指针变量 
    					这个变量指向一个无返回值 并带有一个int类型参数地函数
    
    				   sighandler_t signal(int signum, sighandler_t handler);
    
    			函数功能: 捕捉对应地信号 使其按照指定地方式去处理 
    			参数列表:
    						signum: 你要捕捉哪个信号  要捕捉地那个信号地信号值 
    						
    						handler: 信号的处理方式  一般有如下三种: 
    								  a.自定义的函数
    									这个函数为无返回值 但是带一个int的参数(用来保存收到的那个信号的信号值)的函数
    									
    									大概格式: 
    									void my_signal_handle(int sig)
    									{
    										//用户自定义处理
    									}
    										
    								  b.SIG_IGN    忽略该信号
    								  
    								  c.SIG_DFL    default 采用操作系统默认的处理方式 
    			
    						返回值: 
    					成功返回信号的上一次的处理方式 
    					失败 返回SIG_ERR 同时errno被设置
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    5.pause

    NAME
    				   pause - wait for signal
    
    			SYNOPSIS
    				   #include 
    
    				   int pause(void);
    				   
    				   
    				让进程停在那里 等待某个信号的到来。直到收到信号
    				
    				返回值: 
    						当一个信号被捕捉 且信号处理函数返回后返回 这种情况下返回-1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    实现pause

    #include 
    #include  
    #include 
    #include 
    #include 
    #include 
    
    void mysign(int sign)
    {
    	if(sign==SIGCHLD)
    	{
    		printf("child is die!\n");
    
    	}
    
    
    }
    
    int main()
    {
    
    	signal(SIGCHLD,mysign);
    	pid_t pid=fork();
    	if(pid ==-1)
    	{
    		perror("fork error\n");
    		exit(1);
    	}
    	else if(pid ==0)
    	{
    		sleep(2);
    		printf("I am child!\n");
    		return 0;
    	}
    	else if(pid >0)
    	{
    		int ret=pause();
    		printf("ret==%d\n",ret);
    		wait(NULL); //回收子进程
    		printf("my name is father process!\n");
    	}
    
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    IDEA 启动 java web 老项目
    Mockito 简单示例
    App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
    【C语言】自定义类型:结构体【结构体内存具详细】,枚举,联合
    【Java】垃圾回收
    Flink -- window(窗口)
    考虑阶梯式碳交易机制与电制氢的综合能源系统热电优化(Matlab代码实现)
    C++ 函数
    嵌入式Linux 开发经验:注册一个 misc 设备
    基于springboot框架的快递代取跑腿服务系统
  • 原文地址:https://blog.csdn.net/weixin_46836491/article/details/126813909