nginx源码学习,普通进程和守护进程的区别,文件描述符,守护进程示例

普通进程

  • 1、父进程是bash,退出了消亡
  • 2、占据bash终端

守护进程

  • 1、生存周期长,一般是操作系统启动时启动,操作系统关闭时关闭
  • 2、守护进程和终端没有关联,终端结束,守护进程不会
  • 3、守护进程实在后台运行 ./LinuxTestC -&,不会占据终端
    linux本身就有很多守护进程,30~50个

特点

  • 1、大多数守护进程都是超级,用户特权级别运行
  • 2、守护进程没有终端,所以tty显示‘?’
  • 3、内核守护进程以无控制终端启动
  • 4、普通守护进程可能是守护进程调用了setsid创建新的会话,创建的

守护进程编写规则

  • 1、umask(0) 原因自行百度
  • 2、fork子线程,父线程退出,让出终端,子线程setsid,创建新的会话,与当前bash终端脱离关系
    ps -efj
    ppid父进程为0 ,cmd中带中括号的都是内核守护进程
    init pid=1的内核守护进程,受领孤儿进程,控制进程的顺序
    没有[]的,普通用户级别守护进程
    在这里插入图片描述

文件描述符

文件描述符:正数,用来表示一个文件,打开/创建时,返回一个正数,后续对文件的操作都会用到
linux中有三个特殊的文件描述符,分别为

  • 0、一般表示标准输入,如键盘,对应符号常量,STDIN_FILENO
  • 1、一般表示标准输出,如屏幕,对应符号常量,STDOUT_FILENO
  • 3、一般表示标准错误,如屏幕,对应符号常量,STDERR_FILENO

类unix操作系统,默认用0(STDIN_FILENO)来读入,1(STDOUT_FILENO)输出
everything is file
程序运行起来,0,1,2自动打开,并指向对应的设备

write(1, "hello_world\n", 13);

输入输出重定向

输出重定向,标准输出文件描述符,重新指向一个文件
输出重定向,在shell中用大于号表示 ‘>’:ls > myInfo
输入重定向,在shell中用小于号表示 ‘<’:car < myInfo
cat < myInfo > myOutInfo

空设备
/dev/null:特殊的设别文件,丢弃一些写入的文件
cat > /dev/null

守护进程书写

守护进程通过终端启动,但是运行之后和终端没有关系
一般把守护进程的0,1重定向到/dev/null,确保守护进程不从键盘接收任何数据
也不吧输出结果输出到屏幕
int fd;
打开空设备
fd = open("/dev/null", 0_RDWR);
dup2()复制文件描述符,将第一个参数的设备赋给第二个参数的设备,第二个参数的设备内容会被覆盖
重定向输入到空射别
dup2(fd, STDIN_FILENO);
重定向输出到空设备
dup2(fd, STDOUT_FILENO);
if (fd > STDERR_FILENO)
close(fd);

守护进程特点

  • 1、守护进程不会收到的信号
    • 1.1:守护进程不会受到来自内核的,SIGHUP信号,如果收到了,肯定时另外的进程发送的该SIGHUP信号
      所以通常作为了通知信号,表示配置文件被修改,要立即生效
      nginx就是这样做的,./nginx -s reload就是直接kill -1 processId直接发送GISHUP信号给
      nginx的master守护进程

    • 1.2、也不会收到来自内核的,SIGINT(ctrl+\),SIGWINCH(终端窗口大小改变)信号

守护进程和后台进程的区别;

1、守护进程和终端没有关系,但是后台进程是有关系的,甚至能输入输出
2、进程关闭,守护进程继续执行,而后台进程则接收到SIGHUP信号,消亡

一个守护进程范例

int nginx_start_method()
{
	int fd;
	switch (fork())
	{
	case -1:
		return -1;
	case 0:
		break;
	default:
		exit(0);
	}
	//一定要创建新的会话,不然bash退出
	//守护线程必然销毁
	if (setsid() == -1)
	{
		return -1;
	}
	umask(0);

	fd = open("/dev/null", O_RDWR);
	if (dup2(fd, STDIN_FILENO) == -1)
	{
		return -1;
	}
	if (dup2(fd, STDOUT_FILENO) == -1)
	{
		return -1;
	}
	if (fd > STDERR_FILENO)
	{
		if (close(fd) == -1)
		{
			return -1;
		}
	}
	return 1;

}
int main()
{
	if (nginx_start_method() == -1)
	{
		write(STDOUT_FILENO, "failed\n", 8);
		return -1;
	}
	for (;;)
	{
		sleep(1);
		write(1, "nginx start success\n", 21);
	}
}
发布了157 篇原创文章 · 获赞 167 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40666620/article/details/103244614
今日推荐