LinuxIPC通信之信号(C+Python实现)

Linux信号通俗的来说也就是软中断,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。

在linux中信号有下面这64个,其中信号有两种分类:

(1)可靠性方面:可靠信号与不可靠信号

信号值位于SIGRTMIN及SIGRTMAX之间

不可靠信号是信号值小于SIGRTMIN的信号

Linux下的不可靠信号问题主要指的是信号可能丢失

(2)与时间的关系上:实时信号与非实时信号

非实时信号都不支持排队,都是不可靠信号

实时信号都支持排队,都是可靠信号

规则信号

信号编号名称默认动作说明
1SIGHUP终止终止控制终端或进程
2SIGINT终止由键盘引起的终端(Ctrl-c)
3SIGQUITdump控制终端发送给进程的信号, 键盘产生的退出(Ctrl-\),
4GIGILLdusmp非法指令引起
5SIGTRAPdumpdebug中断
6SIGABRT/SIGIOTdump异常中止
7SIGBUS/SIGEMTdump总线异常/EMT指令
8SIGFPEdump浮点运算溢出
9SIGKILL终止强制杀死进程(大招, 进程不可捕获)
10SIGUSR1终止用户信号, 进程可自定义用途
11SIGSEGVdump非法内存地址引起
12SIGUSR2终止用户信号, 进程可自定义用途
13SIGPIPE终止向某个没有读取的管道中写入数据
14SIGALRM终止时钟中断(闹钟)
15SIGTERM终止进程终止(进程可捕获)
16SIGSTKFLT终止协处理器栈错误
17SIGCHLD忽略子进程退出或中断
18SIGCONT继续如进程停止状态则开始运行
19SIGSTOP停止停止进程运行
20SIGSTP停止键盘产生的停止
21SIGTTIN停止后台进程请求输入
22SIGTTOU停止后台进程请求输出
23SIGURG忽略socket发送紧急情况
24SIGXCPUdumpCPU时间限制被打破
25SIGXFSZdump文件大小限制被打破
26SIGVTALRM终止虚拟定时时钟
27SIGPROF终止profile timer clock
28SIGWINCH忽略窗口尺寸调整
29SIGIO/SIGPOLL终止I/O可用
30SIGPWR终止电源异常
31SIGSYS/SYSUNUSEDdump系统调用异常

 

python:

接收信号:signal.signal(sig,action)

sig为某个信号,action为该信号的处理函数

发送信号:os.kill(pid, sig)

#!/usr/bin/python3

import signal
import os

def sighandler(sig,sighandler):

    if sig == signal.SIGINT:
        print("recv the signal:%d"%sig)
        exit(0)
    elif sig == signal.SIGUSR1:
        print("recv the signal:%d,so i will kill myself,byebye!"%sig)
        os.kill(os.getpid(),signal.SIGTERM) 
signal.signal(signal.SIGINT,sighandler)
signal.signal(signal.SIGUSR1,sighandler)
while True:
    str1 = input("please input \"kill\":")
    if str1 == "kill":
       os.kill(os.getpid(),signal.SIGUSR1)

C:

1、int sigemptyset(sigset_t *set);

该函数的作用是将信号集初始化为空。

2、int sigfillset(sigset_t *set);

该函数的作用是把信号集初始化包含所有已定义的信号。

3、int sigaddset(sigset_t *set, int signo);

该函数的作用是把信号signo添加到信号集set中,成功时返回0,失败时返回-1。

4、int sigdelset(sigset_t *set, int signo);

该函数的作用是把信号signo从信号集set中删除,成功时返回0,失败时返回-1.

5、int sigismember(sigset_t *set, int signo);

该函数的作用是判断给定的信号signo是否是信号集中的一个成员,如果是返回1,如果不是,返回0,如果给定的信号无效,返回-1;

6、int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

该函数可以根据参数指定的方法修改进程的信号屏蔽字。新的信号屏蔽字由参数set(非空)指定,而原先的信号屏蔽字将保存在oset(非空)中。如果set为空,则how没有意义,但此时调用该函数,如果oset不为空,则把当前信号屏蔽字保存到oset中。

how 的不同取值及操作如下所示:

如果sigpromask成功完成返回0,如果how取值无效返回-1,并设置errno为EINVAL。

注意:调用这个函数才能改变进程的屏蔽字,之前的函数都是为改变一个变量的值而已,并不会真正影响进程的屏蔽字。

7、int sigpending(sigset_t *set);

该函数的作用是将被阻塞的信号中停留在待处理状态的一组信号写到参数set指向的信号集中,成功调用返回0,否则返回-1,并设置errno表明错误原因。

8、int sigsuspend(const sigset_t *sigmask);

该函数通过将进程的屏蔽字替换为由参数sigmask给出的信号集,然后挂起进程的执行。注意操作的先后顺序,是先替换再挂起程序的执行。程序将在信号处理函数执行完毕后继续执行。如果接收到信号终止了程序,sigsuspend()就不会返回,如果接收到的信号没有终止程序,sigsuspend()就返回-1,并将errno设置为EINTR。

//  
//  Description: 本程序阻塞除SIGKILL和SIGSTOP之外的所有信号10秒钟
//               在此期间给本程序发信号,观察效果。10秒钟之后解除
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void sighandler(int sig)
{
	fprintf(stderr, "catch %d.\n", sig);
}

int main(int argc, char **argv)
{
	sigset_t sigs;
	sigemptyset(&sigs);

	int i;
	for(i=SIGHUP; i<=SIGRTMAX; i++)
	{
		if(i == SIGKILL || i == SIGSTOP)
			continue;

		signal(i, sighandler);
		sigaddset(&sigs, i);
	}

	printf("[%d]: blocked signals for a while...\n", getpid());
	sigprocmask(SIG_BLOCK, &sigs, NULL);
	sleep(10);

	printf("[%d]: unblocked signals.\n", getpid());
	sigprocmask(SIG_UNBLOCK, &sigs, NULL);
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值