Linux learning summary (15) process group, session, daemon

Process group

  Process group, also called job, is a new feature added by BSD to Unix around 1980, representing a collection of one or more processes, each process belongs to a process group, in the parameters of waitpid function and kill function The concept of process group designed by operating system is to simplify the management of multiple processes.
  When the parent process creates a child process, the default child process and the parent process belong to the same process group, process group ID = the first process ID (group leader process), so the group leader process ID is equal to its process group ID
  can use kill -SIGKILL-Process group ID (negative) to kill all processes in the entire process group.
  The group leader process can create a process group, create a process in the process group, and then terminate. As long as there is a process in the process group, the process group exists, regardless of whether the leader process is terminated.
  Process group life cycle: the process group is created until the last process leaves (terminated or transferred to another process group).
  A process can set the process group ID for itself or its child processes.
  Use the following command to view the process group ID related information:

ps ajx

Insert picture description here

Process group related functions

Get the process group ID of the current process
 pid_t getpgrp(void); Always return the process group ID of the caller

Get the process group ID of the specified process
 pid_t getpgid(pid_t pid); Success: 0; Failure: -1, set errno
if pid = 0, then the function is the same as getpgrp.

Changing the process group that a process belongs to by default is usually used to join an existing process group or create a new process group.
int setpgid(pid_t pid,pid_t pgid); Success 0, failure -1
will add the process corresponding to parameter 1 to the process group corresponding to parameter 2.
Note:
1. If you change the child process to a new group, you should fork and before exec.
2. Permission issues, non-root processes can only change child processes created by themselves, or processes that have permission to operate.
Exercise: Modify the process group ID of the child process

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

int main(void)
{
    
    
    pid_t pid;

    if ((pid = fork()) < 0) {
    
    
        perror("fork");
        exit(1);
    } else if (pid == 0) {
    
    
        printf("child PID == %d\n",getpid());
        printf("child Group ID == %d\n",getpgid(0)); // 返回组id
        //printf("child Group ID == %d\n",getpgrp()); // 返回组id
        sleep(7);
        printf("----Group ID of child is changed to %d\n",getpgid(0));
        exit(0);

    } else if (pid > 0) {
    
    
        sleep(1);
        setpgid(pid,pid);           //让子进程自立门户,成为进程组组长,以它的pid为进程组id

        sleep(13);
        printf("\n");
        printf("parent PID == %d\n", getpid());
        printf("parent's parent process PID == %d\n", getppid());
        printf("parent Group ID == %d\n", getpgid(0));

        sleep(5);
        setpgid(getpid(),getppid()); // 改变父进程的组id为父进程的父进程
        printf("\n----Group ID of parent is changed to %d\n",getpgid(0));

        while(1);
    }

    return 0;
}

Conversation

To create a session, you need to pay attention to the following 6 points:
1. The calling process cannot be the process group leader. The process becomes the first process of the new session.
2. The process becomes the leader process of a new process group.
3. Root permission is required (not required for ubuntu)
4. The new session discards the original control interruption, and the session does not have a controlling terminal.
5. If the calling process is the leader process, an error will be returned
. 6. When establishing a new session, call fork first, the parent process terminates, and the child process calls setsid.

getsid function

Get the session ID to which the process belongs
pid_t getsid(pid_t pid); returns the session ID of the calling process if it succeeds, and returns -1 if it fails,
pid is 0 to identify the current process session ID
ps ajx:

  • a: Not only lists the processes of the current user, but also lists the processes of all other users
  • j: List information related to job control
  • x: Not only lists processes that have a controlling terminal, but also processes that do not have a controlling terminal

The leader process cannot be the first process of the new session, the first process of the new session must become the leader process

setsid function

Create a session and set the process group ID with your own ID, which is also the new session ID.
pid_t setsid(void); successfully returns the session ID of the calling process, and returns -1 on failure
. The process that called the setsid function is both the new president and New leader
exercise: fork a child process and make it create a new session

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

int main(void)
{
    
    
    pid_t pid;

    if ((pid = fork())<0) {
    
    
        perror("fork");
        exit(1);

    } else if (pid == 0) {
    
    

        printf("child process PID is %d\n", getpid());
        printf("Group ID of child is %d\n", getpgid(0));
        printf("Session ID of child is %d\n", getsid(0));

        sleep(10);
        setsid();       //子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程

        printf("Changed:\n");

        printf("child process PID is %d\n", getpid());
        printf("Group ID of child is %d\n", getpgid(0));
        printf("Session ID of child is %d\n", getsid(0));

        sleep(20);

        exit(0);
    }

    return 0;
}

Daemon

  The daemon process is a background service process in Linux. It is usually independent of the control interrupt and periodically executes a certain task or waits to process certain events. It usually uses a name ending in d.
  Some system service processes in the Linux background have no control interruption, cannot directly interact with users, and do not accept the influence of user login and logout. They are always running. They are all daemon processes, such as: the realization of the pre-reading and slowing output mechanism; ftp Server; nfs server, etc.
  To create a daemon, the most critical step is to call the setsid function to create a new session and become the sission leader.

Create a daemon

1. Create the child process, and the parent process exits.
All the work is carried out in the child process formally out of the control terminal
2. Create a new session in the child process The
sesid() function creates a new session, so that the child process is completely out of control
3 . Change the current directory to the root directory
chdir() function to prevent occupying the unmountable file system, or change it to other paths
. 4. Reset the file permissions mask
umask() function to
prevent inherited file creation masks and deny certain permissions. Increase the flexibility of the daemon.
5. Close the file descriptor. The
inherited open file will not be used, waste system resources and cannot be uninstalled
. 6. Start executing the daemon's regular core tasks.
7. The daemon process exits the handler model.

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

void daemonize(void)
{
    
    
    pid_t pid;
    /*
     * * 成为一个新会话的首进程,失去控制终端
     * */
    if ((pid = fork()) < 0) {
    
    
        perror("fork");
        exit(1);
    } else if (pid != 0) /* parent */
        exit(0);
    setsid();
    /*
     * * 改变当前工作目录到/目录下.
     * */
    if (chdir("/") < 0) {
    
    
        perror("chdir");
        exit(1);
    }
    /* 设置umask为0 */
    umask(0);
    /*
     * * 重定向0,1,2文件描述符到 /dev/null,因为已经失去控制终端,再操作0,1,2没有意义.
     * */
    close(0);
    open("/dev/null", O_RDWR);
    dup2(0, 1);
    dup2(0, 2);
}

int main(void)
{
    
    
    daemonize();
    while(1); /* 在此循环中可以实现守护进程的核心工作 */
}

Guess you like

Origin blog.csdn.net/bureau123/article/details/112652932