免费发布黄页广告网站,漳州网站建设去博大a优,佛山网站开发公司,手机制作视频教程日志是网络服务器程序在后台以守护进程的形式运行时#xff0c;处理情况的描述被打印到了日志文件里面#xff0c;方便维护人员查看。
1.前台进程与后台进程 左边会话输入命令 sleep 10000 代表进程后台运行#xff0c;右边会话输入命令 sleep 20000可以看到命令行解…日志是网络服务器程序在后台以守护进程的形式运行时处理情况的描述被打印到了日志文件里面方便维护人员查看。
1.前台进程与后台进程 左边会话输入命令 sleep 10000 代表进程后台运行右边会话输入命令 sleep 20000可以看到命令行解释器直接卡住了。 STAT S就是前台进程的意思STAT S就是后台进程。可以看到后台运行的进程并不影响命令行解释器bash进程的运行而前台进程sleep 20000运行的时候bash进程无法运行了。所以能得出结论一个会话中只能有一个前台进程。
2. 会话与终端 PPID父进程ID
PID进程ID
PGID进程组ID
SID会话
TTY终端 会话是一个进程组任务的集合。在xshell模拟的Linux终端上一个会话在被打开的时候就会启动一个bash进程bash进程是用于对用户输入的命令进行分析解释并返回结果到该会话的终端文件TTY中的。那么bash进程自然就是该会话的第一个进程。可以看到上图红色标记COMMAND-sleep 10000与COMMAND - -bash的SID都是2917而bash的PID和PGID也都是2917。这是什么意思呢一个会话中第一个进程的PID就会作为SID同理一个进程组中第一个进程PID就是进程组的PGID一个进程组至少有一个进程。 可以看到我们把hello world重定向到了/dev/pts/4这个文件下结果在右边的会话中显示出来了。这是为什么呢在/dev/pts/路径下存在着各个会话的终端文件在A会话中输入命令bash进程对命令进行解释后返回的结果就默认输出到A会话的终端文件。
3.前台任务与后台任务切换 jobs 查看当前会话进程组 可以看到每个进程组任务前面都有[1] [2]这样的任务编号。 fg 后台任务切换成前台任务 ctrlz 暂停前台任务 bg 在后台运行任务 4.为什么要创建守护进程
创建一个会话就会可以创建新的前后台任务那么销毁会话可能就会影响会话内的所有任务。所以一般网络服务器为了不受到用户的登录注销的影响都是以守护进程的方式运行。 守护进程就是为了让任务不受所在会话的注销的影响为该进程可以创建一个新的会话。 #include unistd.hpid_t setsid(void);setsid 创建一个新会话如果调用进程不是进程组组长。调用进程是新会话的领导者也是新进程组的组长并且没有控制终端。 这调用进程的进程组 PGID 和会话 SID 被设置为 调用进程的PID。 进程pcb里面是会包含当前进程的工作路径的这也就是我们在open一个文件的时候如果没有就创建文件就会在当前路径下的原因。 /dev/null是一个“黑洞”文件不能从中读取任何数据也不能向其写入任何数据。 5.如何创建守护进程 1. 使用setsid()创建一个新的会话 2. setsid(), 调用进程不能是组长我们怎么保证自己不是组长呢创建子进程。 3. 必要操作a. 忽略异常信号 b. 0,1,2文件描述符要做特殊处理 c. 进程的工作路径可能需要更改 setsid函数: 代码
#pragma once#include signal.h
#include unistd.h
#include cstdlib#include log.hpp
#include err.hpp
#include cerrno
#include cstring
#include sys/types.h
#include sys/stat.h
#include fcntl.hvoid Daemon()
{// 忽略信号signal(SIGCHLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);// 让子进程去setsidif (fork() 0)exit(0);// 为当前进程组任务创建新的会话pid_t ret setsid();if ((int)ret -1){logMessage(Fatal, setsid error,code:%d ,string: %s\n, errno, strerror(errno));exit(SETSID_ERR);}// 更改工作路径到根目录// chdir(/);//0,1,2做特殊处理int fd open(/dev/null,O_RDWR);//可读可写方式打开黑洞文件if(fd0){logMessage(Fatal, open error,code:%d ,string: %s\n, errno, strerror(errno));exit(OPEN_ERR);}dup2(fd,0);dup2(fd,1);dup2(fd,2);close(fd);}
由于进程组组长长不能单起一个会话的原则所以创建子进程作为守护进程守护进程是一个孤儿进程。 其实也可以直接用Unix标准库函数daemon函数创建守护进程: NAME daemon - run in the background SYNOPSIS #include unistd.h int daemon(int nochdir, int noclose); 当nochdir为0时daemon将更改进程的工作路径为根目录。 当noclose为0时daemon将进城的STDIN, STDOUT, STDERR都重定向到/dev/null。一般情况下这个参数都是设为0的。