Linux中信号处理举例

Linux处理ctrl+c信号的例子

当按下ctrl+c时如果代码正在执行sleep则会停止睡眠,调用信号处理函数。中断位置可能位于for循环代码段的任意位置,中断位置不可控。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <signal.h>
void h(int s)
{
	printf("抽空处理int信号\n");
}
main()
{
	int sum=0;
	int i;
	signal(SIGINT,h);
	sigset_t sigs;
    
	for(i=1;i<=10;i++)
	{
		sum+=i;
		sleep(1);
	}
	printf("sum=%d\n",sum);
	printf("Over!\n");
}

信号屏蔽的例子1

当按下ctrl+c时不会调用信号处理函数,当循环执行完毕后会调用信号处理函数,并且printf(“Over!\n”)会被执行。

 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
#include <stdio.h>
#include <signal.h>

void h(int s)
{
	printf("抽空处理int信号\n");
}

main()
{
    int sum=0;
    int i;
    // 声明信号集合
    sigset_t sigs;
    signal(SIGINT,h);
    // 清空集合
    sigemptyset(&sigs);
    // 加入屏蔽信号
    sigaddset(&sigs,SIGINT);
    // 屏蔽信号
    sigprocmask(SIG_BLOCK,&sigs,0);
    for(i=1;i<=10;i++)
    {
        sum+=i;
        sleep(1);
    }
    printf("sum=%d\n",sum);
    // 消除屏蔽信号
    sigprocmask(SIG_UNBLOCK,&sigs,0);
    // 如果在上面按下ctrl+c,在此句不执行
    printf("Over!\n");
}

当在循环中按下ctrl+c后,该函数输出结果为:

1
2
3
sum=55
抽空处理int信号
Over!

信号屏蔽的例子2

 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
#include <stdio.h>
#include <signal.h>
// 信号处理函数
void h(int s)
{
	printf("抽空处理int信号\n");
}
main()
{
	int sum=0;
	int i;
	signal(SIGINT,h);
	sigset_t sigs,sigp,sigq;
	sigemptyset(&sigs);
	sigemptyset(&sigp);
	sigemptyset(&sigq);
	
	sigaddset(&sigs,SIGINT);
	sigprocmask(SIG_BLOCK,&sigs,0);
	for(i=1;i<=10;i++)
	{
		sum+=i;
		sigpending(&sigp);
		if(sigismember(&sigp,SIGINT))
		{
			printf("SIGINT在排队!\n");
			// 是信号SIGINT有效
			sigsuspend(&sigq);
			// 函数调用完毕后信号SIGINT无效
		}
		sleep(1);
	}
	printf("sum=%d\n",sum);
    // 消除屏蔽信号
	sigprocmask(SIG_UNBLOCK,&sigs,0);
	printf("Over!\n");
}

该例子可以实现在指定的代码处处理信号。 其中sigsuspend函数原先如下:

1
int sigsuspend(const sigset_t *mask);

函数解释:屏蔽新的信号,原来的屏蔽信号失效。是一个阻塞函数,该函数屏蔽mask信号;对非mask信号不屏蔽,信号处理函数调用完毕该函数返回;如果非mask信号没有信号处理函数,则此函数不返回。即返回条件:信号发生且信号为非屏蔽信号且信号必须要调用信号处理函数完毕。