Linux System Programming 41 Process Control-Daemon Process

Zombie process : In UNIX terms, a process that has been terminated, but its parent process has not yet processed it (obtaining information about terminating the child process and releasing the resources it still occupies) becomes a zombie process.

Orphan process : If the parent process exits first and the child process has not yet completed, then the child process will be entrusted to the init process at this time. At this time, the parent process of the child process is the init process (process No. 1).

Daemon process : generally refers to the background service process in Linux. It is a process with a long life cycle. For example, its parent process is the init process, which is usually independent of the control terminal, that is, it does not accept direct operations from computer users. The daemon is a special orphan process.

Session : A session is a collection of one or more process groups. Usually a session starts when the user logs in and ends when the user logs out. During this period, all processes run by the user belong to the session.

Process group : In addition to a process ID, each process also belongs to a process group. A process group is a collection of one or more processes. Each process group has a leader process, and the process ID of the leader process is equal to the process group ID.

NAME
       setsid - creates a session and sets the process group ID
创建会话,并设置进程组的ID

SYNOPSIS
       #include <unistd.h>

       pid_t setsid(void);

If the process calling setsid() is not the leader process of a process group, a session is created. That is, the parent process cannot call setsid() to create a session, it can only be called by the child process. The process that calls setsid() will become the leader of the session, and will become the leader of the current new process group. And get away from the control terminal.

setsid() is used to create a new session and has the following three functions:
1 Let the process get rid of the control of the original session
2 Let the process get rid of the control of the original process group
3 Let the process get rid of the control of the original controlling terminal

Daemon:
1 The background service program
2 is separated from the control terminal , and the user cannot interact with the daemon through the terminal. TTY ==?
3 Long-term, periodic execution of a task, that is , the parent process is the init process , that is, the process No. 1
4 is not affected by the user login, logout of influence that is not the current session control

So, why call the setsid function when creating a daemon? Because the first step of creating a daemon process calls the fork function to create a child process, and then exits the parent process. Because when the fork function is called, the child process copies the parent process's session period, process group, control terminal, etc., although the parent process exits, but the session period, process group, control terminal, etc. have not changed. Therefore, this is still It is not independent in the true sense, but the setsid function can make the process completely independent and get rid of the control of other processes.

A process must be the parent process, but the daemon process is a bit different. Generally, after the child process is called, according to the previous logic, when the child process is running, the parent process will always wait for the child process to complete and release resources, that is, wait() collects the body. But the daemon process does not need to wait (), because it will run for a long time, the parent process and the parent process of the parent process, etc. do not need to wait forever, so just entrust it to the init process.

mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps axj
  PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
父进程ID  : PPID
进程ID : PID
组进程ID : PGID
会话ID : SID

Experiment: the creation of a daemon

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <fcntl.h>

#define FILENAME "/tmp/out"

static int craetdeamon(void)
{
	pid_t pid;
	int fd;	
	
	pid = fork();
	if(pid < 0)
	{
		perror("fork()");
		return -1;
	}
	
	if(pid > 0) //父进程结束
	{
		printf("%d\n",getpid());
		exit(0);
	}
		

	fd = open("/dev/null",O_RDWR);
	if(fd < 0)
	{	
		perror("open()");
		return -1;
	}

//重定向 0 1  2 文件描述符
	dup2(fd,0);
	dup2(fd,1);
	dup2(fd,2);	
	if(fd > 2)
	{
		close(fd);
	}

//创建守护进程
	setsid();
	
	chdir("/");

	return 0;
}

int main(int argc,char* argv[])
{

	FILE* fp;
	int i;


	if(craetdeamon())
	{
		exit(1);
	}
	
	fp = fopen(FILENAME,"w");
	if(fp == NULL)
	{
		perror("fopen()");
		exit(1);
	}

	for(i = 0; ;i++)
	{
		fprintf(fp,"%d\n",i);
		fflush(fp);
		sleep(1);
	}
	
	
	exit(0);
}

mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps axj
   ...
  1662   3141   3141   3141 ?            -1 Ss    1000   0:00 ./a.out
  2959   3188   3188   2959 pts/2      3188 R+    1000   0:00 ps axj

父进程是 1662 并不是init进程

mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps 1662
   PID TTY      STAT   TIME COMMAND
  1662 ?        Ss     0:00 /sbin/upstart --user
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ tail -f /tmp/out
1693
1694
1695
1696
1697
1698
1699
1700
1701

mhr@ubuntu:~/Desktop/xitongbiancheng/test$ kill 3141
最后记得杀死 守护进程

It is found that the parent process of the daemon process is not the init process at this time, and later learned that the newer ubuntu uses the upstart process to replace the init process to adopt the orphan process.

The reason for redirecting 0 1 2 three file descriptors:
the child process created with the fork function will inherit some opened files from the parent process. The daemon has lost contact with its controlling terminal. Therefore, the characters input from the terminal cannot reach the daemon process, and the characters output by the conventional method (such as printf) in the daemon process cannot be displayed on the terminal. Therefore, the three files with file descriptors 0, 1, and 2 (commonly referred to as input, output, and error) have lost their value and should be closed or redirected.

The child process created with fork will inherit the working directory of the parent process. If the daemon runs on a device, and when the device is uninstalled, an exception will occur, and the device is busy. The usual practice is to let the root directory ("/") be the current working directory of the daemon. The above problems can be avoided.
chdir("/");

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/113962786