Linux_C编程—信号的捕捉和处理

信号的捕捉处理概述

前面介绍了信号的基本信息和信号的发送,这里总结一下Linux中进程对信号的捕捉和处理,进程收到信号一般会设置一个信号处理函数来专门执行接收到信号后的操作,类似于中断一样。
在信号处理函数中,可以根据信号的不同来执行相应的操作,也可以读取信号所携带的信息。
Linux系统中对信号的处理主要由signal()函数和sigaction()函数来处理,有时还会用到pause()函数,下面对这些函数一一介绍。(SIGKILL和SIGSTOP信号不可以被捕捉或忽略)

signal()函数

signal()函数用来设置进程接收到信号的动作,在shell下输入man signal可以获取其函数原型:

#include <signal.h>
typedef void ( *sighandler_t ) ( int );
sighandler_t signal( int signum, sighandler_t handler );
  • signum是指定信号的编号
  • handler是对应信号处理函数的指针,它所指向的函数类型是sighandler_t,且所指向的函数有一个int型参数,返回值为void
  • signal()函数执行成功时返回信号处理函数的指针,有错误时返回SIG_ERR(即-1)

下面通过一段代码来实现signal()对信号的捕捉和处理:

#include <stdio.h>
#include <signal.h>

/* 信号处理函数 */
void handler_sigint( int signo )
{
	printf("recv SIGINT\n");
}

int main( void )
{
	/* 安装信号处理函数 */
	signal( SIGINT, handler_sigint );
	while( 1 )
		;
	return 0;
}

可以在shell中按下<Ctrl+C>来向进程发送SIGINT信号,进程收到信号后会立即执行信号处理函数,即在屏幕上打印出:recv SIGINT
要结束进程的时候按下<Ctrl+>即可(发送了SIGSTOP信号),也可以使用kill命令结束进程

程序说明:
程序首先使用signal()函数安装了SIGINT的信号处理函数,然后进入死循环,当接收到SIGIINT信号时,立即跳转执行信号处理函数,从而打印出信息,然后返回主函数继续死循环。

sigaction()函数

sigaction()函数也可以对信号进行捕捉和调用信号处理函数,在shell下输入man sigaction可以获取其函数原型:

#include <signal.h>

int sigaction( int signum, const struct sigaction *act, struct sigaction *oldact );
  • signum就是指定的信号的编号
  • act指向新的信号处理函数
  • oldact会存储旧的信号处理函数
  • struct 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可以是常数SIG_DFL或SIG_IGN,也可以是一个函数名,指向信号处理函数
  • sa_sigaction也是用来指向信号处理函数的,但其有三个参数,第一个参数是信号编号、第二个参数是指向siginfo_t的指针,此参数可以用来传递数据、第三个参数一般不用
  • sa_mask声明了一个信号集
  • sa_flags成员用来说明信号处理的一些相关处理操作

下面通过一段代码来熟悉一下:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

/* 定义全局变量 */
int temp = 0;

/* 信号处理函数 */
void handler_sigint( int signo )
{
	printf("recv SIGINT\n");
	sleep( 5 );
	temp++;
	printf("the value of temp is :%d\n", temp);
	printf("in handler_sigint, after sleep\n");
}

int main( void )
{
	struct sigaction act;
	/* 配置act结构体 */
	act.sa_handler = handler_sigint;
	/* 表示支持信号的嵌套处理 */
	act.sa_flags = SA_NOMASK;
	/* 安装信号处理函数,act中就包含了信号处理函数的信息 */
	sigaction( SIGINT, &act, NULL );
	while( 1 )
		;
	return 0;
}

程序的执行结果如下:
在这里插入图片描述
当把act.sa_flags = SA_NOMASK;注释去掉后的执行结果如下:
在这里插入图片描述
去掉后,sigaction按照默认方式阻塞正在排队的信号,因为SIGINT是不可靠信号,不可靠信号不支持排队,造成了信号丢失

pause()函数

pause()函数使调用进程挂起,直至捕捉到一个信号,在shell下输入man pause可获取函数原型:

#include <unistd.h>

int pause( void )

pause()函数会令目前进程暂时进入睡眠状态,直到被信号所中断,该函数只返回-1。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Linux 下编写 C 语言程序需要一个编译器,如 GCC。可以使用命令行工具编写代码,并使用 GCC 编译器编译代码。例如,在命令行中输入 "gcc -o programname programname.c" 可以将 programname.c 文件编译为可执行文件 programname。然后在命令行运行 "./programname" 即可运行编译后的程序。 ### 回答2: Linux下C语言编程是非常常见的一种开发环境与方式。Linux操作系统提供了完善的C语言开发工具链,包括编译器、调试工具、开发库等,因此在Linux下进行C语言编程是非常方便和高效的。 首先,Linux下最常用的C语言编译器是GNU编译器套装(GCC)。GCC是一个开源的编译器套件,支持多种编程语言,其中包括C语言。使用GCC编译器,可以将C语言源代码编译成可执行的机器代码,从而在Linux操作系统上运行。 其次,Linux提供了丰富的调试工具,如GNU调试器(GDB)。GDB是一个功能强大的调试工具,可以通过设置断点、查看变量值、跟踪程序执行流程来帮助开发人员进行代码调试。使用GDB可以快速定位并解决代码中的错误。 此外,Linux还提供了大量的开发库和工具,如标准C库(libc)、各种系统库和第三方库等。这些库和工具能够极大地提升C语言编程的效率和功能,开发人员可以利用这些库来实现各种功能,如文件操作、网络通信、图形界面等。 在Linux下进行C语言编程还有一个显著的优势就是开源社区的支持。Linux有庞大的开源社区,有着丰富的资源和经验,开发人员可以从中获取帮助和学习。在开源社区中,开发人员可以共享自己的代码、学习他人的经验,并且可以参与到各种开源项目中去,提升自己的技能和知识。 综上所述,Linux下C语言编程是非常强大和便利的。通过Linux提供的工具链、库和开源社区的支持,开发人员可以高效地进行C语言编程,实现各种功能和项目。 ### 回答3: Linux下的C语言编程是一种广泛应用的编程方式。Linux作为一种开源操作系统,在C语言编程方面具有许多优势和特点。 首先,Linux下的C语言编程可以充分利用Linux操作系统的强大功能和丰富的系统接口。通过使用Linux的系统调用接口,我们可以直接对文件、进程、网络等进行操作,实现更高级的功能。同时,Linux提供了许多方便的开发工具和库,比如GCC编译器、C库,使得C语言编程更加方便和高效。 其次,Linux下的C语言编程具有良好的可移植性。由于Linux操作系统的开源性质,C语言编程在Linux下编写的程序可以在其他操作系统上进行移植。这为开发者提供了更大的自由度和灵活性,使得他们能够更好地跨平台开发和移植应用程序。 另外,Linux下的C语言编程也提供了强大的调试和性能优化工具。开发者可以使用诸如gdb、valgrind等工具对C程序进行调试和性能分析,以找出潜在的问题并提高程序的效率。这些工具的存在大大提高了开发者对程序的控制和管理能力。 总结而言,Linux下的C语言编程是一种功能强大、可移植性高且开发工具丰富的编程方式。通过利用Linux操作系统的强大功能和丰富接口,开发者可以编写高效、稳定且可移植的应用程序。这使得Linux下的C语言编程成为了许多开发者的首选。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值