Linux提高:信号(不会)

文章目录

题目

创建一个守护进程 ,使用 Linux 信号机制,让守护进程退出。

代码

/*************************************************************************
    > File Name: main.c
    > Author: 杨永利
    > Mail: 1795018360@qq.com 
    > Created Time: 2021年07月16日 星期五 18时38分59秒
 ************************************************************************/

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXFILE 3
// 创建守护进程
void init_daemon(void)
{
	pid_t pid = 0;
	int i = 0;
	// 第一次 fork,使之成为守护进程
	pid = fork();
	if (pid < 0) {
		// 判断返回值,fork 函数出错
		perror("fork error.");
		exit(1);
	}
	else if (pid > 0) {
		// 父进程,退出
		exit(0);
	}
	// 子进程
	// 使子进程成为新的会话组长和进程组长,摆脱原会话控制,,摆脱原进程组控制, 摆脱控制终端控制
	setsid();
	// 改变工作目录,防止其他原因 ,导致工作目录不存在
	// 第二次 fork,
	pid = fork();
	if (pid < 0) {
		// 判断返回值,fork 函数出错
		perror("fork error.");
		exit(1);
	}
	else if (pid > 0) {
		// 父进程,退出
		exit(0);
	}
	//关闭打开的文件描述符,避免资源浪费
	for (i = 0; i < MAXFILE; ++i) {
		// close(i);
	}
	chdir("/");
	// 重设文件权限掩码
	umask(0);
	return;
}
void mysighandler_t(int arg)
{
	printf("收到信号 SIGUSR1 系统开始退出 \n");
	exit(1);
}
int main(int argc, char const *argv[])
{
	// 注册一个信号 : 告诉 linux 内核 当有信号 SIGUSR1 发给我的时候 , 请你调用这个 apimysighandler_t
	signal(SIGUSR1, mysighandler_t);
	//创建守护进程
	init_daemon();
	printf("守护进程启动...\n");
	while (1)
	{
		sleep(5);
		printf("程序正在后台运行...\n");
	}
	return 0;
}

知识回顾

守护进程

守护进程概念

守护进程:Daemon(精灵)进程,是 Linux 中的后台服务进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。一般采用以 d 结尾的名字。

创建守护进程模型

  1. 创建子进程,父进程退出
    所有工作在子进程中进行形式上脱离了控制终端。
  2. 在子进程中创建新会话
    setsid()函数,使子进程完全独立出来,脱离控制。
  3. 改变当前目录为根目录
    chdir()函数,防止占用可卸载的文件系统,也可以换成其它路径。
  4. 重设文件权限掩码
    umask()函数,防止继承的文件创建屏蔽字拒绝某些权限,增加守护进程灵活性。
  5. 关闭文件描述符
    继承的打开文件不会用到,浪费系统资源,无法卸载。
  6. 开始执行守护进程核心工作
  7. 守护进程退出处理程序模型

信号

信号:是进程间通信(IPC)方式之一。

信号机制

A 给 B 发送信号,B 收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号,处理完毕再继续执行。与硬件中断类似——异步模式。但信号是软件层面上实现的中断,早期常被称为“软中断”。

每个进程收到的所有信号,都是由内核负责发送的。

信号名称 信号说明 默认处理
SIGABRT 由程序调用 abort时产生该信号。 程序异常结束。 进程终止并且产生core文件
SIGALRM timer到期, 有alarm或者setitimer 进程终止
SIGBUS 总线错误,地址没对齐等。取决于具体硬件。 结束终止并产生core文件
SIGCHLD 进程停止或者终止时,父进程会收到该信号。 忽略该信号
SIGCONT 让停止的进程继续执行 继续执行或者忽略
SIGFPE 算术运算异常,除0等。 进程终止并且产生core文件。
SIGHUP 终端关闭时产生这个信号 进程终止
SIGILL 代码中有非法指令 进程终止并产生core文件
SIGINT 终端输入了中断字符ctrl+c 进程终止
SIGIO 异步I/O,跟SIGPOLL一样。 进程终止
SIGIOT 执行I/O时产生硬件错误 进程终止并且产生core文件
SIGKILL 这个信号用户不能去捕捉它。 进程终止
SIGPIPE 往管道写时,读者已经不在了,或者往一个已断开数据流socket写数据。 进程终止
SIGPOLL 异步I/O,跟SIGIO一样。 进程终止
SIGPROF 有setitimer设置的timer到期引发 。 进程终止
SIGPWR Ups电源切换时 进程终止
SIGQUIT Ctrl+\,不同于SIGINT,这个是会产生core dump文件的。 进程终止并且产生core文件
SIGSEGV 内存非法访问,默认打印出segment fault 进程终止并且产生core文件
SIGSTOP 某个进程停止执行,该信号不能被用户捕捉。 进程暂停执行
SIGSYS 调用操作系统不认识的系统调用。 进程终止并且产生core文件
SIGTERM 有kill函数调用产生。 进程终止
SIGTRAP 有调试器使用,gdb 进程终止并且产生core文件
SIGTSTP Ctrl+z,挂起进程。 进程暂停
SIGTTIN 后台程序要从终端读取成数据时。 进程暂停
SIGTTOU 后台终端要把数据写到终端时。 进程暂停
SIGURG 一些紧急的事件,比如从网络收到带外数据。 忽略
SIGUSR1 用户自定义信号 进程终止
SIGUSR2 用户自定义信号 进程终止
SIGVTALRM 有setitimer产生。 进程终止
上一篇:Webbench结果分析及原理


下一篇:21_线程控制与通信