精华内容
下载资源
问答
  • 1、什么是守护进程守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行...守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由...

    941bd89f135b4df73771089680885f8b.png

    1、什么是守护进程

    • 守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或循环等待处理某些事件的发生;
    • 守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机才随之一起停止运行;
    • 守护进程一般都以root用户权限运行,因为要使用某些特殊的端口或者资源;
    • 守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由init接管;

    2、有哪些常见的守护进程

    • 日志服务进程 syslogd
    • 数据库守护进程 mysqld

    3、创建守护进程的步骤

    1)fork()创建子进程,父进程exit()退出

    这是创建守护进程的第一步。由于守护进程是脱离控制终端的,因此,完成第一步后就会在Shell终端里造成程序已经运行完毕的假象。之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到了与控制终端的脱离,在后台工作。

    2)在子进程中调用 setsid() 函数创建新的会话

    在调用了fork()函数后,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而 setsid() 函数能够使进程完全独立出来。

    3)再次 fork() 一个孙进程并让子进程退出

    为什么要再次fork呢,假定有这样一种情况,之前的父进程fork出子进程以后还有别的事情要做,在做事情的过程中因为某种原因阻塞了,而此时的子进程因为某些非正常原因要退出的话,就会形成僵尸进程,所以由子进程fork出一个孙进程以后立即退出,孙进程作为守护进程会被init接管,此时无论父进程想做什么都随它了。

    4)在孙进程中调用 chdir() 函数,让根目录 ”/” 成为孙进程的工作目录

    这一步也是必要的步骤,使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统(如“/mnt/usb”)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常的做法是让"/"作为守护进程的当前工作目录,这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp,改变工作目录的常见函数是chdir。

    5)在孙进程中调用 umask() 函数,设置进程的文件权限掩码为0

    文件权限掩码是指屏蔽掉文件权限中的对应位。比如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。设置文件权限掩码的函数是umask。在这里,通常的使用方法为umask(0)。

    6)在孙进程中关闭任何不需要的文件描述符

    同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。

    在上面的第2)步之后,守护进程已经与所属的控制终端失去了联系。因此从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2 的3个文件(常说的输入、输出和报错)已经失去了存在的价值,也应被关闭。

    7)守护进程退出处理

    当用户需要外部停止守护进程运行时,往往会使用 kill 命令停止该守护进程。所以,守护进程中需要编码来实现 kill 发出的signal信号处理,达到进程的正常退出。

    4、守护进程的代码实现

    #include 

    5、用系统函数daemon实现

    #include 

    a17305259b400900bf0577557ba650e5.png
    展开全文
  • 1、什么是守护进程守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行...守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由...

    1、什么是守护进程

    守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或循环等待处理某些事件的发生;

    守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机才随之一起停止运行;

    守护进程一般都以root用户权限运行,因为要使用某些特殊的端口或者资源;

    守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由init接管;

    2、有哪些常见的守护进程

    日志服务进程 syslogd

    数据库守护进程 mysqld

    3、创建守护进程的步骤

    (1) fork()创建子进程,父进程exit()退出

    这是创建守护进程的第一步。由于守护进程是脱离控制终端的,因此,完成第一步后就会在Shell终端里造成程序已经运行完毕的假象。之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到了与控制终端的脱离,在后台工作。

    (2) 在子进程中调用 setsid() 函数创建新的会话

    在调用了fork()函数后,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而 setsid() 函数能够使进程完全独立出来。

    (3) 再次 fork() 一个孙进程并让子进程退出

    为什么要再次fork呢,假定有这样一种情况,之前的父进程fork出子进程以后还有别的事情要做,在做事情的过程中因为某种原因阻塞了,而此时的子进程因为某些非正常原因要退出的话,就会形成僵尸进程,所以由子进程fork出一个孙进程以后立即退出,孙进程作为守护进程会被init接管,此时无论父进程想做什么都随它了。

    (4) 在孙进程中调用 chdir() 函数,让根目录 ”/” 成为孙进程的工作目录

    这一步也是必要的步骤,使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统(如“/mnt/usb”)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常的做法是让"/"作为守护进程的当前工作目录,这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp,改变工作目录的常见函数是chdir。

    (5) 在孙进程中调用 umask() 函数,设置进程的文件权限掩码为0

    文件权限掩码是指屏蔽掉文件权限中的对应位。比如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。设置文件权限掩码的函数是umask。在这里,通常的使用方法为umask(0)。

    (6) 在孙进程中关闭任何不需要的文件描述符

    同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。

    在上面的第2)步之后,守护进程已经与所属的控制终端失去了联系。因此从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2 的3个文件(常说的输入、输出和报错)已经失去了存在的价值,也应被关闭。

    (7) 守护进程退出处理

    当用户需要外部停止守护进程运行时,往往会使用 kill 命令停止该守护进程。所以,守护进程中需要编码来实现 kill 发出的signal信号处理,达到进程的正常退出。

    4、守护进程的代码实现

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    static bool flag = true;

    void create_daemon();

    void handler(int);

    int main()

    {

    time_t t;

    int fd;

    create_daemon();

    struct sigaction act;

    act.sa_handler = handler;

    sigemptyset(&act.sa_mask);

    act.sa_flags = 0;

    if(sigaction(SIGQUIT, &act, NULL))

    {

    printf("sigaction error.\n");

    exit(0);

    }

    while(flag)

    {

    fd = open("/home/mick/daemon.log",

    O_WRONLY | O_CREAT | O_APPEND, 0644);

    if(fd == -1)

    {

    printf("open error\n");

    }

    t = time(0);

    char *buf = asctime(localtime(&t));

    write(fd, buf, strlen(buf));

    close(fd);

    sleep(60);

    }

    return 0;

    }

    void handler(int sig)

    {

    printf("I got a signal %d\nI'm quitting.\n", sig);

    flag = false;

    }

    void create_daemon()

    {

    pid_t pid;

    pid = fork();

    if(pid == -1)

    {

    printf("fork error\n");

    exit(1);

    }

    else if(pid)

    {

    exit(0);

    }

    if(-1 == setsid())

    {

    printf("setsid error\n");

    exit(1);

    }

    pid = fork();

    if(pid == -1)

    {

    printf("fork error\n");

    exit(1);

    }

    else if(pid)

    {

    exit(0);

    }

    chdir("/");

    int i;

    for(i = 0; i < 3; ++i)

    {

    close(i);

    }

    umask(0);

    return;

    }

    5、用系统函数daemon实现

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    static bool flag = true;

    void handler(int);

    int main()

    {

    time_t t;

    int fd;

    if(-1 == daemon(0, 0))

    {

    printf("daemon error\n");

    exit(1);

    }

    struct sigaction act;

    act.sa_handler = handler;

    sigemptyset(&act.sa_mask);

    act.sa_flags = 0;

    if(sigaction(SIGQUIT, &act, NULL))

    {

    printf("sigaction error.\n");

    exit(0);

    }

    while(flag)

    {

    fd = open("/home/mick/daemon.log",

    O_WRONLY | O_CREAT | O_APPEND, 0644);

    if(fd == -1)

    {

    printf("open error\n");

    }

    t = time(0);

    char *buf = asctime(localtime(&t));

    write(fd, buf, strlen(buf));

    close(fd);

    sleep(60);

    }

    return 0;

    }

    void handler(int sig)

    {

    printf("I got a signal %d\nI'm quitting.\n", sig);

    flag = false;

    }

    以上就是C++实现LINUX守护进程代码实例的详细内容,更多关于C++ LINUX守护进程的资料请关注脚本之家其它相关文章!

    展开全文
  • 对于我们一般写的程序,主进程是最初始的父进程。 子进程 对于父进程而言, 父进程创建的进程, 子进程只能对应一个父进程。 守护进程 我们常言的daemon 进程,是子进程的一种状态,标记子进程与父进程同死。如果...

    一、摘要
    详解父进程、子进程、守护进程的区别,例子稍候补充

    二、定义区别
    主进程
    程序执行的入口,可以理解为常用的main 函数

    父进程
    对于子进程而言, 子进程的创造者,可有多个子进程。 任何进程都有父进程,追根溯源是系统启动程序。对于我们一般写的程序,主进程是最初始的父进程。

    子进程
    对于父进程而言, 父进程创建的进程, 子进程只能对应一个父进程。

    守护进程
    我们常言的daemon 进程,是子进程的一种状态,标记子进程与父进程同死。如果没有标记daemon , 则杀死父进程,与子进程的运行状态没有半分影响。

    僵尸进程
    因为某些子进程没有设置daemon 属性,如果杀死父进程,其子进程将会变成“僵尸进程”。僵尸进程的父进程将成为init 进程的子进程。

    为避免僵尸进程,一般:
    设置父进程的SIGCHLD信号处理函数为 SIG_IGN (忽略信号)
    fork 两次并杀次以及子进程,令二级子进程成为僵尸进程,成为init子进程,并被清理

    展开全文
  • Linux 进程Linux 上值得关注几种进程分别是:孤儿进程僵尸进程守护进程孤儿进程是指子进程还在运行时候,其父进程退出了,此时该子进程就变成 “孤儿进程”,孤儿进程会被 1 号 init(systemd) 进程收养,后续该...

    Linux 进程

    Linux 上值得关注的几种进程分别是:

    孤儿进程

    僵尸进程

    守护进程

    孤儿进程是指子进程还在运行的时候,其父进程退出了,此时该子进程就变成 “孤儿进程”,孤儿进程会被 1 号 init(systemd) 进程收养,后续该子进程的退出清理工作就交由 init 进程来管理。

    僵尸进程是指父进程 fork 了子进程后,子进程运行完毕退出,但父进程并没有使用 wait 或者 waitpid 来获取子进程的状态信息,导致子进程的进程描述符依然存在系统中,如果使用 ps 、top 等命令会看到进程状态为 Z,这种进程就是僵尸进程。僵尸进程有危害,如果大量产生僵尸进程,会大量消耗系统资源。

    守护进程是指运行在后台的一种特殊进程,它脱离于控制终端,并且周期性地执行某种任务或等待处理某些发生的事件。linux 上大多数系统进程都是守护进程。

    本文重点研究一下守护进程。

    守护进程

    先来看一个进程图:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND

    1 1162 1162 1162 ? -1 Ss 0 0:00 /usr/sbin/sshd -D

    1162 1460 1460 1460 ? -1 Ss 0 0:00 \_ sshd: root@pts/0

    1460 1464 1464 1464 pts/0 1507 Ss 0 0:00 | \_ -bash

    1464 1506 1506 1464 pts/0 1507 S 0 0:00 | \_ ./hello_world

    1464 1507 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1508 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1509 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1510 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1511 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1162 1479 1479 1479 ? -1 Ss 0 0:00 \_ sshd: root@pts/1

    1479 1483 1483 1483 pts/1 1516 Ss 0 0:00 | \_ -bash

    1483 1516 1516 1483 pts/1 1516 S+ 0 0:00 | \_ ./hello_world

    1162 1517 1517 1517 ? -1 Ss 0 0:00 \_ sshd: root@pts/2

    1517 1521 1521 1521 pts/2 1536 Ss 0 0:00 \_ -bash

    1521 1536 1536 1521 pts/2 1536 R+ 0 0:00 \_ ps ajxf

    上面是使用 ps ajxf 命令的输出的其中一部分,只展示了终端相关的进程情况。可以看到这台机器上开了 3 个终端,每个终端上有不同的进程在运行。

    接下来就以上面的结果为例作说明。

    会话和进程组

    会话也就是 session,每一个终端对应一个会话。当有新用户登录 shell 之后,可以把整个 shell 程序看成一个会话。会话随着终端用户登录而创建,随终端用户退出而终止。

    一个会话可以包含多个进程,每个进程都属于一个进程组,父进程创建了子进程,它们就形成一个进程组,并且父进程成为进程组组长;采用进程组的目的是能够统一控制信号的分发,给一个进程组发送信号,信号会发送给进程组中的每一个进程。

    PPID: 父进程 ID

    PID: 进程 ID

    PGID: 进程组 ID

    SID: 会话 ID

    TTY: shell 对应的虚拟终端,使用 tty 可以查看当前 shell 对应的虚拟终端(如上图,展示了 3 个终端)

    demo 验证

    分别准备两个版本的程序员入门代码:

    hello_world.cc

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10#include

    #include

    int main(){

    std::cout << "Hello world" << std::endl;

    while (true) {

    sleep(2);

    }

    return 0;

    }

    编译命令:

    1g++ hello_world.cc -o hello_world

    hello_world_fork.cc

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46#include

    #include

    void child_work(){

    std::cout << "child "<< getpid() << " :Hello world" << std::endl;

    while (true) {

    sleep(2);

    }

    }

    void father_work(){

    pid_t pid = fork();

    if (pid == 0) {

    child_work();

    return;

    }

    pid = fork();

    if (pid == 0) {

    child_work();

    return;

    }

    pid = fork();

    if (pid == 0) {

    child_work();

    return;

    }

    pid = fork();

    if (pid == 0) {

    child_work();

    return;

    }

    while (true) {

    sleep(2);

    }

    }

    int main(){

    father_work();

    return 0;

    }

    编译命令:

    1g++ hello_world_fork.cc -o hello_world_fork

    上面的代码很简单,一个是直接打印 “hello world”,另外一个是 fork 了多个子进程打印 “hello world”。

    分别启动 3 个终端,在第一个终端上执行:

    1

    2./hello_world &

    ./hello_world_fork

    在第二个终端上执行:

    1./hello_world

    在第三个终端上进行查询:

    1ps ajxf

    可以看到如下的结果:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND

    1 1162 1162 1162 ? -1 Ss 0 0:00 /usr/sbin/sshd -D

    1162 1460 1460 1460 ? -1 Ss 0 0:00 \_ sshd: root@pts/0

    1460 1464 1464 1464 pts/0 1507 Ss 0 0:00 | \_ -bash

    1464 1506 1506 1464 pts/0 1507 S 0 0:00 | \_ ./hello_world

    1464 1507 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1508 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1509 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1510 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1507 1511 1507 1464 pts/0 1507 S+ 0 0:00 | \_ ./hello_world_fork

    1162 1479 1479 1479 ? -1 Ss 0 0:00 \_ sshd: root@pts/1

    1479 1483 1483 1483 pts/1 1516 Ss 0 0:00 | \_ -bash

    1483 1516 1516 1483 pts/1 1516 S+ 0 0:00 | \_ ./hello_world

    1162 1517 1517 1517 ? -1 Ss 0 0:00 \_ sshd: root@pts/2

    1517 1521 1521 1521 pts/2 1536 Ss 0 0:00 \_ -bash

    1521 1536 1536 1521 pts/2 1536 R+ 0 0:00 \_ ps ajxf

    可以看到 3 个 shell 会话的会话 ID 分别是 1464、1483、1521,每一个 bash 进程是由 sshd 这个进程创建而来的,可以看到上面每个 bash 进程的父进程分别是 1460、1479、1517。

    如果父进程创建了多个子进程,那么这些进程构成一个进程组,其父进程成为进程组组长,如上的 hello_world_fork 进程,可以看到他们的父进程是 1507,并且它们同属于一个进程组 1507。

    上面还值得注意的是 /usr/sbin/sshd -D 这个进程,可以看到它的父进程 ID 是 1,并且 TTY 没有具体值,即没有控制终端,这个进程就是守护进程。

    c++ 实现守护进程

    源码可以在我的 github 找到:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101#include

    #include

    #include

    #include

    #include

    bool daemon(){

    int fd;

    switch (fork()) {

    case -1:

    // fork 出错,直接返回

    return false;

    case 0:

    // 第一个子进程

    break;

    default:

    // 父进程直接退出

    exit(0);

    }

    // setsid() 函数会创建一个新会话,目的是让上面创建的第一个子进程脱离控制终端和进程组,并让这个子进程成为会话组组长,与原来的登陆会话和进程组脱离

    // 到这,第一个子进程已经成为无终端的会话组组长,但是对于一个会话组组长来说,它依然能够重新申请打开一个控制终端

    if (setsid() == -1 ) {

    // setsid 失败,直接返回

    return false;

    }

    // 第二次 fork

    // 目的是为了让进程不再成为会话组长,避免它重新申请打开控制终端

    switch (fork()) {

    case -1:

    // fork 出错,直接返回

    return false;

    case 0:

    // 第二个子进程产生

    break;

    default:

    // 第一个子进程退出

    exit(0);

    }

    // 重新设置文件权限的掩码,目的是去除终端用户的默认文件、文件夹权限,比如 centos 普通用户 umask 为 0022,默认创建的文件权限为 644,文件夹权限为 755

    // 如果重新设置掩码 umask 为 0 的话,那么默认创建的文件权限就是 666,文件夹就是 777

    umask(0);

    // 守护进程不应该在终端有任何的输出,使用 dup2 函数把 stdin,stdout,stderr 重定向到 /dev/null

    fd = open("/dev/null", O_RDWR);

    if (fd == -1) {

    return false;

    }

    if (dup2(fd, STDIN_FILENO) == -1) {

    return false;

    }

    if (dup2(fd, STDOUT_FILENO) == -1) {

    return false;

    }

    #if 0

    if (dup2(fd, STDERR_FILENO) == -1) {

    return;

    }

    #endif

    if (fd > STDERR_FILENO) {

    if (close(fd) == -1) {

    return false;

    }

    }

    return true;

    }

    void do_work(){

    FILE *fp = fopen("/tmp/daemon.log", "w");

    if (!fp) {

    return;

    }

    while (true) {

    fprintf(fp, "ABCDEDFGH\n");

    fflush(fp);

    sleep(10);

    }

    fclose(fp);

    }

    int main(){

    if (!daemon()) {

    return -1;

    }

    do_work();

    return 0;

    }

    上面的代码注释其实已经很详细了,这里单独再说两点:

    两次 fork 的问题

    第二次 fork 的目的是为了让第一次 fork 产生的第一个子进程不再成为新会话的会话组长,避免它再次申请控制终端;如果能够确保第一次 fork 之后不会有控制终端的申请,那么第二次 fork 不是必须的。比如 nginx、redis 都是只有一次 fork.

    umask(0)

    重设文件权限掩码。每一个用户都有默认的文件权限,可以执行 umask 命令查看当前用户的文件权限掩码。

    1

    2#umask

    0022

    文件默认最高权限为 666,也就是 -rw-rw-rw-,文件夹默认最高权限为 777,也就是 drwxrwxrwx,如果 umask 为 0022 ,那么该用户创建的文件以及文件夹的权限分别为 644 和 755。重设文件权限掩码为 0000 的目的就在此,确保守护进程的文件操作权限为最高。

    The END

    守护进程的应用场景很广泛,尤其是一些保活的场景会经常用得到。

    Blog:

    2019-10-02 于杭州

    展开全文
  • 一个守护进程的父进程是init进程,它是一个孤儿进程,没有控制终端,所以任何输出,无论是向标准输出设备stdout还是标准出错设备stderr的输出都被丢到了/dev/null中。守护进程一般用作服务器进程,如httpd,s...
  • linux 守护进程

    2020-11-29 13:37:45
    守护进程 linux 服务端程序很多都是以守护进程的方式对外提供服务, linux 系统本身也有很多守护进程,例如kthreadd用来创建内核进程, kswapd是内存换页守护进程,... 守护进程的父进程一般是系统1号进程,例如initd或者s
  • Linux 守护进程

    2019-09-28 22:00:08
    Linux 守护进程 守护进程,也就是通常所说Daemon进程,是Linux后台服务进程。 守护进程常常在系统引导装入时启动,在系统关闭时终止。 编写守护进程 1. 创建子进程,父进程退出 由于守护进程是脱离控制终端...
  • 1、什么是守护进程守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行...守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由...
  • 1、什么是守护进程守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行...守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由...
  • 守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由init接管; 2、有哪些常见的守护进程 日志服务进程 syslogd 数据库守护进程 mysqld 3、创建...
  • linux守护进程

    千次阅读 2018-03-08 21:05:10
    这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。 总之,除开这些特殊性以外,守护进程与普通进程基本上没有什么区别。 因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性...
  • Linux守护进程

    2018-05-21 20:36:47
    Linux守护进程1) 守护进程也称为Daemon进程,是Linux中的后台服务进程。守护进程用于执行特定的系统任务。守护进程的生命周期较长,一些守护进程在系统引导时启动,一直运行至系统关闭。2) Linux系统大多数服务都...
  • 一个守护进程的父进程是init进程,它是一个孤儿进程,没有控制终端,所以任何输出,无论是向标准输出设备stdout还是标准出错设备stderr的输出都被丢到了/dev/null中。守护进程一般用作服务器进程,如httpd,sys...
  • 守护进程:也称为精灵进程,守护进程是一个在后台运行并且不受任何终端控制进程。守护进程脱离于终端是为了避免进程在执行过程中信息在任何终端上显示并且进程也不会被任何终端所产生终端信息所打断。 2 创建...
  • linux守护进程的创建

    2013-03-05 20:58:00
    下面完成了这样一个功能,创建一个守护进程,...Linux系统中大多数服务进程都是由守护进程实现。 二、创建守护进程 创建子进程,父进程退出 此时,子进程变成孤儿进程,在后台运行。此时,子进程表...
  • 使用linux守护进程

    2021-04-16 14:18:26
    Linux的大多数服务器就是用守护进程的方式实现的。如web服务器进程http等。守护进程在后台运行,类似于Windows中的系统服务。 参考代码 编写守护进程程序的要点: (1)让程序在后台执行。方法是调用fork()产生...
  • Linux守护进程的编程

    2014-10-07 01:48:02
    一. 守护进程及其特性  守护进程最重要的特性是后台运行;其次,守护进程必须与其运行前...最后,守护进程的启动方式有其特殊之处------它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程cro
  • 7 Linux 守护进程

    2021-01-21 21:29:27
    创建会话:* 不能是进程组长* 创建会话进程成为新进程组组长* 部分Linux发行版需要root* 创建出新会话会丢弃原有控制终端* 一般步骤:fork()在\创建子进程,父进程死,子进程执行创建会话操作创建会话:setsid()...
  • Linux 守护进程创建

    2019-05-27 19:04:00
    1. 守护进程: 是Linux中的后台服务进程。它是一个生存期较长的...2. 创建守护进程的步骤: 1)创建子进程,父进程退出fork();  2)在子进程中创建新会话 setsid();  3)改变当前目录为根目录chdir("/")...
  • linux守护进程daemon

    2015-08-31 12:05:14
    linux守护进程: linux很多系统服务都是守护进程,例如本地系统服务crond计划任务 , 网络服务:web httpd 如何将一个进程转换为守护进程呢? 一.概念:  进程: 每一个进程都有父进程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 509
精华内容 203
关键字:

linux守护进程的父进程是

linux 订阅