进程-守护进程创建、会话、控制终端

(一)守护进程的特点
进程运行起来除了拥有可执行文件加载到内存上之外,还需要操作系统分配进程控制块、CPU寄存器、堆栈。守护进程通常在系统启动时运行,系统结束时关闭。很多服务器都是守护进程运行。

(1)始终在后台运行:守护进程不占用终端,和终端无关,一直在后台运行,随linux操作系统终止而终止,无法手动关闭。
(2)独立于任何的终端。
(3)周期性的执行某种任务或者等待处理特定的事件。
注:守护进程属于后台进程,但是jobs只能查看当前终端下的后台进程,而守护进程和终端无关,因此jobs无法查看守护进程。

(二)系统调用和库
系统调用:由linux内核提供的函数
库函数:存放在函数库中的函数。库函数具有明确的功能、入口调用参数和返回值。一般封装系统调用函数提供对外的API。

(三)fork(系统调用)

			#include <unistd.h>
			pid_t fork(void);

(1)子进程是从fork后面开始执行,即紧接着是return返回值。
(2)fork();生成两个进程:父进程和子进程。父子进程运行时,相互独立,互不影响,并发运行;究竟是父进程先于子进程执行,还是子进程先于父进程执行,这取决于内核的系统调度
(3)父进程的ppid是/bin/bash

(四)守护进程-会话、控制终端
linux以会话session、进程组的方式管理进程,每个进程属于一个进程组。
(1)会话
会话是一个或者多个进程组的集合。通常用户打开一个终端时,系统会创建一个会话,所有通过该终端运行的进程都属于这个会话。
终端关闭时,所有相关的进程都会结束。

(五)守护进程的创建
(1)创建子进程,父进程退出;让子进程变成孤儿进程,被init进程收养,使子进程在后台运行

			if(fork() > 0)
			{
				exit(0);
			}

(2)setsid子进程创建新的会话

a.子进程成为新的会话组长
b.子进程脱离原先的终端
  #include <unistd.h>
   pid_t setsid(void);
			if(setsid() < 0)
			{
				exit(-1);
			}

(3)chdir更改当前的工作目录

	更改为稳定的不会被卸载删除的目录
	      #include <unistd.h>
		  int chdir(const char *path);	 //相当于cd命令

(4)umask重新设置文件权限掩码

		   #include <sys/types.h>
	       #include <sys/stat.h>
	
	       mode_t umask(mode_t mask);
	eg:
				if(umask(0) < 0)
				{
					exit(-1);
				}

(5)关闭从父进程继承而来的文件描述符

扫描二维码关注公众号,回复: 9897373 查看本文章
		关闭从父进程继承而来的文件描述符,
		已脱离终端,stdin,stdout,stderr无法再使用。
		int i;
		for(i = 0; i < getdtablesize(); i++)	// i < 3
		{
			close(i);
		}

程序如下:

	1 #include <stdio.h>
	  2 #include <stdlib.h>
	  3 #include <unistd.h>
	  4 #include <sys/types.h>
	  5 #include <sys/stat.h>
	  6 
	  7 
	  8 int main(int argc, const char *argv[])
	  9 {
	 10     int i;
	 11     pid_t pid;
	 12 
	 13     pid = fork();
	 14     if(pid < 0)
	 15     {
	 16         perror("fork error");
	 17         exit(-1);
	 18     }
	 19 
	 20     if(pid > 0)
	 21     {
	 22         exit(0);
	 23     }
	 24 
	 25     if(setsid() < 0)
	 26     {
	 27         exit(-1);
	 28     }
	 29 
	 30     chdir("./");
	 31 
	 32     if(umask(0) < 0)                                                                                                                                                
	 33     {
	 34         exit(-1);
	 35     }
	 36 
	 37     for(i = 0; i < getdtablesize(); i++)
	 38     {
	 39         //close(i);
	 40     }
	 41     printf("setsid successs\n");
	 42 
	 43     while(1)
	 44     {
	 45         sleep(1);
	 46     }
	 47 
	 48     return 0;
	 49 }
	~              

(六)daemon函数

daemon(0, 0); //函数自动生成守护进程

NAME
       daemon - run in the background

SYNOPSIS
       #include <unistd.h>

       int daemon(int nochdir, int noclose);
发布了13 篇原创文章 · 获赞 0 · 访问量 128

猜你喜欢

转载自blog.csdn.net/m0_46170433/article/details/104915996