守护进程

来源:互联网 发布:ubuntu 12 输入法 编辑:程序博客网 时间:2024/05/01 13:03

守护进程是在后台运行并且没有控制终端的进程。

由于守护进程通常没有控制终端,所以,几乎不需要与用户交互。守护进程用于提供哪些没有任何用户交互就可以在后台做得很好的服务。

例如,一个在后台运行观察网络活动并且记录任何可疑通信日志的进程就可以开发成守护进程。

守护进程设计开发守护进程就像开发其他进程一样,但有一件事情即没有控制终端使它与任何其他普通进程区别开来。这就是创建守护进程时的主要设计问题。这可以通过以下步骤实现:
  • 创建一个普通进程(父进程)
  • 从上述父进程内部创建一个子进程
  • 在这个时候,进程的层次关系看起来像:终端 à 父进程 à 子进程
  • 终止父进程
  • 子进程现在成为孤儿然后被init进程收养
  • 在新会话中调用setsid()函数运行这个进程并拥有一个新的用户组
  • 经过以上步骤之后,可以说现在这个进程成为没有控制终端的守护进程
  • 将守护进程的工作目录改为根目录,然后关闭stdin、stdout和stderr文件描述符
  • 让守护进程的主逻辑运行
因此,我们看到,以上步骤为创建守护进程指明了基本设计步骤。C语言fork()函数

按以上所述的设计步骤创建可实际运行的守护进程之前,让我们首先了解一点fork()系统调用的知识。

fork()系统调用创建的进程是一个与父进程完全一样的复制品。这个新进程被称为‘子’进程。

这个系统调用(在父进程中)被调用一次,但返回两次(一次返回父进程,第二次返回子进程)。注意,在fork()系统调用之后,是父进程还是子进程先运行是不确定的。它完全依赖于上下文切换机制。这个调用在子进程中返回0而在父进程中返回子进程的PID。

这个系统调用的一些重要方面如下:

  • 子进程拥有属于自己的惟一的进程ID,而且这一PID与现存任何进程组ID不一致。
  • 子进程的父进程ID与父进程的进程ID相同。
  • 子进程没有继承其父进程的内存锁。
  • 子进程中的进程资源使用和CPU时间计数器重置为0。
  • 子进程挂起信号集初始化为空。
  • 子进程不继承父进程的信号量调节值。
  • 子进程不继承父进程的记录锁。
  • 子进程不继承父进程的定时器。
  • 子进程不继承父进程未完成的异步I/O操作,也不继承父进程的任何异步I/O上下文。
想要更多信息,请阅读这个系统调用的手册页。


A daemon process is a process which runs in background and has no controlling terminal.

Since a daemon process usually has no controlling terminal so almost no user interaction is required. Daemon processes are used to provide services that can well be done in background without any user interaction.

For example a process that runs in background and observes network activity and logs any suspicious communication can be developed as a daemon process.

Daemon Process Design

A daemon process can be developed just like any other process but there is one thing that differentiates it with any other normal process ie having no controlling terminal. This is a major design aspect in creating a daemon process. This can be achieved by :

  • Create a normal process (Parent process)
  • Create a child process from within the above parent process
  • The process hierarchy at this stage looks like :  TERMINAL -> PARENT PROCESS -> CHILD PROCESS
  • Terminate the the parent process.
  • The child process now becomes orphan and is taken over by the init process.
  • Call setsid() function to run the process in new session and have a new group.
  • After the above step we can say that now this process becomes a daemon process without having a controlling terminal.
  • Change the working directory of the daemon process to root and close stdin, stdout and stderr file descriptors.
  • Let the main logic of daemon process run.

So we see that above steps mark basic design steps for creating a daemon.

C fork() Function

Before creating an actual running daemon following the above stated design steps, lets first learn a bit about the fork() system call.

fork() system creates a child process that is exact replica of the parent process. This new process is referred as ‘child’ process.

This system call gets called once (in parent process) but returns twice (once in parent and second time in child). Note that after the fork() system call, whether the parent will run first or the child is non-deterministic. It purely depends on the context switch mechanism. This call returns zero in child while returns PID of child process in the parent process.

Following are some important aspects of this call :

  • The child has its own unique process ID, and this PID does not match the ID of any existing process group.
  • The child’s parent process ID is the same as the parent’s process ID.
  • The child does not inherit its parent’s memory locks.
  • Process resource utilization and CPU time counters are reset to zero in the child.
  • The child’s set of pending signals is initially empty.
  • The child does not inherit semaphore adjustments from its parent.
  • The child does not inherit record locks from its parent.
  • The child does not inherit timers from its parent.
  • The child does not inherit outstanding asynchronous I/O operations from its parent, nor does it inherit  any  asynchronous I/O contexts from its parent.

For more insight information, please read the man page of this system call.

The Implementation

Based on the design as mentioned in the first section. Here is the complete implementation :

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <string.h>

int main(int argc, char* argv[])

{

FILE *fp= NULL;

pid_t process_id = 0;

pid_t sid = 0;

// Create child process

process_id = fork();

// Indication of fork() failure

if (process_id < 0)

{

printf("fork failed!\n");

// Return failure in exit status

exit(1);

}

// PARENT PROCESS. Need to kill it.

if (process_id > 0)

{

printf("process_id of child process %d \n",process_id);

// return success in exit status

exit(0);

}

//unmask the file mode

umask(0);

//set new session

sid = setsid();

if(sid < 0)

{

// Return failure

exit(1);

}

// Change the current working directory to root.

chdir("/");

// Close stdin. stdout and stderr

close(STDIN_FILENO);

close(STDOUT_FILENO);

close(STDERR_FILENO);

// Open a log file in write mode.

fp = fopen ("Log.txt", "w+");

while (1)

{

//Dont block context switches, let the process sleep forsome time

sleep(1);

fprintf(fp, "Logging info...\n");

fflush(fp);

// Implement and call some function that does core workfor this daemon.

}

fclose(fp);

return (0);

}

 

 

Following is the way through which the code was compiled and executed:

$ gcc -Wall deamon.c -o deamon$ sudo ./deamonprocess_id of child process 2936

Just observe that the control immediately came back to the terminal ie the daemon is now not associated to any terminal.

When you check the log.txt file located in the root directory, you could see that this daemon process is running.

$

$ tail -f /Log.txt

Logging info...

Logging info...

Logging info...

Logging info...

Logging info...

Logging info...

Logging info...

Logging info...

Logging info...

Logging info...

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两岁宝宝断奶不喝奶粉怎么办 宝宝两岁了断奶后奶粉不吃怎么办 宝宝断奶两天了不愿意吃奶粉怎么办 一岁四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶后不吃奶粉怎么办 2岁的宝宝不开口说话怎么办 一周岁宝宝断奶不喝奶粉怎么办 八个月宝宝断奶不喝奶粉怎么办 婆家人总是用心机对待娘家人怎么办 婆婆老是背后说我娘家人坏话怎么办 婆家姐带孩子住娘家不走怎么办? 老是想在娘家不想回婆家怎么办 娘家和婆家同时向我借钱怎么办 土地确权后娘家婆家都没有怎么办 结了婚婆家向娘家借钱怎么办? 婆婆的娘家人从我家住怎么办 八个月宝宝断奶后不吃奶粉怎么办 吃母乳的宝宝不吸奶嘴怎么办 宝宝吸了奶嘴不吸母乳怎么办 婴儿吃了奶嘴不吸母乳怎么办 十一个月宝宝断奶不喝奶粉怎么办 孩子三门成绩全不及格家长该怎么办 宝宝快十个月了还不会爬怎么办 小孩写字老把手向里扭曲怎么办 孩子该上四年级了数学差的很怎么办 孩子上三年级了数学成绩好差怎么办 三年级数学老考70-80分怎么办 叛逆期的孩子用死来威胁家长怎么办 叛逆期的孩子抽烟喝酒家长该怎么办 大学遇到不好的老师加课怎么办 两岁的宝宝脾气古怪不听话怎么办 16个月宝宝不听话脾气大怎么办 如果你很害怕去面对一件事怎么办 孩子上幼儿园哭老师不理孩子怎么办 发现幼儿园给孩子吃药片该怎么办 做老师的打学生被家长投诉怎么办 学生认为老师向家长打报告怎么办 老师发打12分的试卷给家长怎么办 孩子在学校顶撞老师不让上学怎么办 被老师骂了不敢去学校怎么办