P

0

点赞

0

回复

544

浏览

Linux守护进程

1 守护进程是什么? 在Linux/UNIX系统引导的时候会开启很多服务,这些服务称为守护进程(Daemon进程)。守护进程是脱离于控制终端并且在后台周期性地执行某种任务或等待处理某些事件的进程,脱离终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的中断信息所终止。 2 创建守护进程步 2.1 创建子进程,退出父进程 为了脱离控制终端需要退出父进程,之后的工作都由子进程完成。在Linux中父进程先于子进程退出会造成子进程成为孤儿进程,而每当系统发现一个孤儿进程时,就会自动由1号进程(init)收养它,这样,原先的子进程就会变成init进程的子进程。 2.2 在子进程中创建新的会话 setsid函数作用:用于创建一个新的会话,并担任该会话组的组长。调用setsid有3个作用 1. 让进程摆脱原会话的控制; 2. 让进程摆脱原进程组的控制; 3. 让进程摆脱原控制终端的控制; 使用setsid函数的目的:由于创建守护进程的第一步调用了fork函数来创建子进程再将父进程退出。由于在调用fork函数时,子进程拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开了。使用setsid函数后,能够使进程完全独立出来,从而摆脱其他进程的控制。 2.3 改变当前目录为根目录 使用fork创建的子进程继承了父进程的当前的工作目录。由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后的使用会造成诸多的麻烦。因此,通常的做法是让根目录”/”作为守护进程的当前工作目录。这样就可以避免上述的问题。如有特殊的需求,也可以把当前工作目录换成其他的路径。改变工作目录的方法是使用chdir函数。 2.4 重设文件权限掩码 文件权限掩码:是指屏蔽掉文件权限中的对应位。例如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限(对应二进制为,rwx, 101)。由于fork函数创建的子进程继承了父进程的文件权限掩码,这就给子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0(即,不屏蔽任何权限),可以增强该守护进程的灵活性。设置文件权限掩码的函数是umask。通常的使用方法为umask(0)。 2.5 关闭文件描述符 用fork创建的子进程也会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸载。在使用setsid调用之后,守护进程已经与所属的控制终端失去了联系,因此从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1、2(即,标准输入、标准输出、标准错误输出)的三个文件已经失去了存在的价值,也应该关闭。 2.6 守护进程退出处理 当用户需要外部停止守护进程时,通常使用kill命令停止该守护进程。所以,守护进程中需要编码来实现kill发出的signal信号处理,达到进程正常退出。 3 DEMO include include include include // open include include include include include define MAXFILE 65535 volatile sig_atomic_t _running = 1; int fd; // signal handler void sigterm_handler(int arg) { } int main() {  / 屏蔽一些有关控制终端操作的信号   防止在守护进程没有正常运转起来时,因控制终端受到干扰退出或挂起   /  signal(SIGINT,// 终端中断  signal(SIGHUP,// 连接挂断 // 终端退出 // 向无读进程的管道写数据 // 后台程序尝试写操作 // 后台程序尝试读操作 // 终止  // test // try cmd: ./test kill s SIGTERM PID  // 1 fork child process and exit father process  if(pid 0)  {    }  // 2 create a new session  // 3 set current path  if(getcwd(szPath, sizeof(szPath)) == NULL)  {      }  else  {      }  // 4 umask 0  // 5 close useless fd i ++i) i ++i)  {    }  // 6 set termianl signal  // open file and set rw limit  if((fd = open("outfile", O_CREAT|O_WRONLY|O_APPEND, 0600)) 0)  {      }  // do sth in loop  while(_running)  {   if (write(fd, buf, strlen(buf)) != strlen(buf))   {            }  // 1 s  }  // print data  if((fd = open("outfile", O_RDONLY)) 0)  {      }  if(read(fd, szBuf, sizeof(szBuf)) == 1)  {      } } /    gcc Wall g o test test.c    ps ux | grep v grep | grep test    tail f outfile    kill s SIGTERM PID   /   ...

linuxprocessdaemon

新建主题 记录代码

学员动态

  • 手**掌在课程中提出了问题:void start...
  • 三**年添加了笔记:我们创建一个分页的类...
  • c**8在课程作业中回复了老师:老师还有一个问题! ...
  • 三**年完成了课程的作业
  • 手**掌向课程作业中提交了代码
  • h**6在课程作业中回复了老师:这样能成吗...
  • 浮**梦在课程作业中回复了老师:不是很懂这道题,可不...
  • c**x创建了代码片段:ASDLKJASL打...
  • I**g在课程作业中回复了老师:请问方法哪里写错了?...
  • 天**君回复了F**k在课程中的问题:欢迎来到天码营学习,...
  • 天**君回复了i**r在课程中的问题:欢迎来到天码营学习,...
  • 白**2在课程中提出了问题:for(T elem...
  • L**9在课程作业中回复了老师:老师,题目提醒中这句...
  • 三**年添加了笔记:首先在UserRep...
  • L**9向课程作业中提交了代码
  • j**a添加了笔记:数学运算中存在自动类...
  • 虚**人向课程作业中提交了代码
  • L**9向课程作业中提交了代码
  • 天**君回复了c**8在课程中的问题:欢迎来到天码营学习,...
  • 手**掌向课程作业中提交了代码
  • _**s向课程作业中提交了代码
  • 天**君评论了h**6在课程中的作业:这是其他同学的作业,...
  • I**y向课程作业中提交了代码
  • I**y向课程作业中提交了代码
  • 浮**梦向课程作业中提交了代码
  • j**a添加了笔记:包(Package)...
  • c**x创建了代码片段:哪里能开发票办证小姐...
  • I**y向课程作业中提交了代码
  • 天**君评论了c**8在课程中的作业:1、Optional...
  • c**8在课程作业中回复了老师:老师您好,有5个小问...
  • h**i向课程作业中提交了代码
  • w**3评论了L**9在课程中的作业:不要直接去获取nam...
  • F**k在课程中提出了问题:我按照课程指导安装了...
  • j**a添加了笔记:不仅仅是使用Java...
  • I**y向课程作业中提交了代码
  • j**a添加了笔记:使用记事本编写Jav...
  • L**1完成了课程的作业
  • j**a添加了笔记
  • 天**君回复了唐**学在课程中的问题:欢迎来到天码营学习,...
  • w**3回复了手**掌在课程中的问题:void 是返回类型...
  • 三**年完成了课程的作业
  • j**a添加了笔记:占用内存空间小的类型...
  • H**g向课程作业中提交了代码
  • I**y向课程作业中提交了代码
  • _**s向课程作业中提交了代码
  • I**y在课程中提出了问题:老师,这里不是很理解...
  • _**s向课程作业中提交了代码
  • _**s向课程作业中提交了代码
  • h**i向课程作业中提交了代码
  • H**g向课程作业中提交了代码
  • c**8评论了h**6在课程中的作业:我也是学生,不是老师...
  • L**9在课程作业中回复了老师:谢谢老师,我试...
  • t**y在课程中提出了问题:老师,已经add,为...
  • I**y向课程作业中提交了代码
  • w**7在课程作业中回复了老师:页面显示是正常的啊,...
  • 天**君回复了p**0在课程中的问题:欢迎来到天码营学习,...
  • j**a添加了笔记:保存代码: 快捷键C...
  • 三**年添加了笔记:上面这种方法解决了B...
  • I**y向课程作业中提交了代码
  • h**6向课程作业中提交了代码
  • w**3回复了白**2在课程中的问题:这叫做for-eac...
  • w**3回复了手**掌在课程中的问题:安装java8重新配...
  • j**a添加了笔记:使用记事本编写Jav...
  • c**8在课程作业中回复了老师:全部回答了!太感谢...
  • 天**君回复了7**4在课程中的问题:欢迎来到天码营学习,...
  • l**5向课程作业中提交了代码
  • I**y在课程中提出了问题:老师,这样的赋值到底...
  • L**1向课程作业中提交了代码
  • w**3回复了t**y在课程中的问题:https://ww...
  • L**9在课程作业中回复了老师:老师,请问我写的这个...
  • c**8在课程中提出了问题:老师啊,这章讲的也太...
  • I**g向课程作业中提交了代码
  • 三**年添加了笔记:给BlogRepos...
  • L**9在课程作业中回复了老师:老师,请问为什么我写...
  • 三**年完成了课程的作业
  • I**y向课程作业中提交了代码
  • w**3评论了L**9在课程中的作业:那是我给的解题思路里...
  • 三**年添加了笔记:为了支持方便的分页功...
  • 手**掌在课程中提出了问题:但是我装8的时候提示...
  • w**3评论了I**g在课程中的作业:public sta...
  • I**y向课程作业中提交了代码
  • I**g向课程作业中提交了代码
  • 三**年添加了笔记:为了支持分页,我们需...
  • w**7完成了课程的作业
  • j**a添加了笔记:包(Package)...
  • I**y向课程作业中提交了代码
  • S**e向课程作业中提交了代码
反馈意见