0%

普通进程、守护进程和后台进程

最近看代码,一些服务进程在main函数中会调用daemon函数创建守护进程,然后继续执行。 又联想到之前项目在调试的时候,一般在shell中会执行多次的程序名后加一个&符号,让进程进入后台执行,还可以看到终端的输出。有时候我们自己写的小程序,在shell中使用程序名执行,查看输出结果。

上面三种进程,分别对应到守护进程、后台进程和前台进程(一般也可以叫普通进程?)。

区别

默认情况下,进程是前台进程,这时就把Shell给占据了,我们无法进行其他操作。对于那些没有交互的进程,我们希望将其在后台启动,可以在启动参数的时候加一个’&’实现这个目的。

守护进程是生存期长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。也就是指daemon和service。比如web服务器, syslog服务。

普通和后台进程在shell退出时,进程也会终止,这个时候可以使用nohup 程序名 &来实现。

1
2
3

nohup ping www.baidu.com &

使用了nohup命令后,会在当前目录下生成一个nohup.out的日志文件,记录的就是命令的输出。

守护进程,就是shell退出,也会运行。

进程查看

守护进程:ps -x

普通进程:ps 或 带参数的其他ps命令

后台进程:jobs 或 前面的上述的那些命令

daemon函数使用

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
 
#include <unistd.h>
#include <stdio.h>


/*
The daemon() function is for programs wishing to detach themselves from the controlling
terminal and run in the background as system daemons.

If nochdir is zero, daemon() changes the process's current working directory to the root
directory ("/"); otherwise, the current working directory is left unchanged.

If noclose is zero, daemon() redirects standard input, standard output and standard error
to /dev/null; otherwise, no changes are made to these file descriptors.

On success daemon() returns zero. If an
error occurs, daemon() returns -1 and sets errno to any of the errors specified for the
fork(2) and setsid(2).

*/
// int daemon(int nochdir, int noclose);


int main(void)
{
fprintf(stderr, "1111 now pid is %d\r\n", getpid());

sleep(1);
if (daemon(0, 1) == 0) {
fprintf(stderr, "create daemon success\r\n");
}

fprintf(stderr, "22222 now pid is %d\r\n", getpid());
sleep(1);

int count = 0;
while (count < 10)
{
fprintf(stderr, "count %d daemon(%d)\r\n", count++, getpid());
sleep(6);
}

fprintf(stderr, "daemon(%d) exit\r\n", count++, getpid());

return 0;
}

我们创建了一个守护进程, 让他运行60s后退出,并输出运行的信息。

程序运行过程中,我们可以退出shell,然后重新进一个shell, 可以通过ps -x看到进程还在运行。

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。