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

新建主题 记录代码

学员动态

  • 天码君回复了l**m在课程中的问题:欢迎来到天码营学习,...
  • x**4向课程作业中提交了代码
  • h**u在课程中提出了问题:老师你好,请问把最后...
  • w**3回复了d**7在课程中的问题:java 严格要求字...
  • z**o在课程作业中回复了老师:请问本地运行能显示如...
  • S**n向课程作业中提交了代码
  • 天码君回复了x**3在课程中的问题:欢迎来到天码营学习,...
  • 天码君回复了O**e在课程中的问题:欢迎来到天码营学习,...
  • f**a添加了笔记:Q1.fo...
  • f**a向课程作业中提交了代码
  • z**8添加了笔记
  • d**7在课程中提出了问题:哦,明白了,谢谢老...
  • l**m向课程作业中提交了代码
  • d**7向课程作业中提交了代码
  • S**n向课程作业中提交了代码
  • w**3评论了x**3在课程中的作业:post post....
  • x**3向课程作业中提交了代码
  • w**3回复了d**7在课程中的问题:代码问题可以直接在代...
  • h**u在课程中提出了问题:老师你好,在第三课的...
  • n**0评论了:受益匪浅,学习笔记 ...
  • c**e添加了笔记:用快捷键CTRL+S...
  • z**8向课程作业中提交了代码
  • 天码君回复了S**n在课程中的问题:欢迎来到天码营学习,...
  • 天码君回复了坦克在课程中的问题:欢迎来到天码营学习,...
  • w**3评论了x**3在课程中的作业:int id...
  • 刘保方向课程作业中提交了代码
  • d**7向课程作业中提交了代码
  • 天码君回复了l**n在课程中的问题:欢迎来到天码营学习,...
  • l**n在课程中提出了问题:老师出现这个情况应该...
  • h**u在课程作业中回复了老师:老师你好,在讲义中有...
  • z**8添加了笔记:Java语言自带的关...
  • f**a向课程作业中提交了代码
  • h**u添加了笔记:每个Java语句都需...
  • S**n完成了课程的作业
  • 刘保方向课程作业中提交了代码
  • 勺**5在课程作业中回复了老师:运行没问题,就是提交...
  • 勺**5向课程作业中提交了代码
  • 天码君回复了x**l在课程中的问题:欢迎来到天码营学习,...
  • f**a添加了笔记:...
  • l**m向课程作业中提交了代码
  • 天码君回复了J**2在课程中的问题:欢迎来到天码营学习,...
  • F**s向课程作业中提交了代码
  • S**n完成了课程的作业
  • w**3回复了h**u在课程中的问题:抱歉,视频只放了wi...
  • w**3评论了x**3在课程中的作业:System.out...
  • d**7在课程中提出了问题:您好,为什么错了...
  • d**7在课程中提出了问题:public voi...
  • d**7在课程中提出了问题:打印出来的HTML必...
  • w**3回复了h**u在课程中的问题:那这是太好了,计算机...
  • S**n完成了课程的作业
  • l**m向课程作业中提交了代码
  • l**m评论了:请问什么是doubl...
  • 天码君回复了y**9在课程中的问题:欢迎来到天码营学习,...
  • d**7在课程中提出了问题:public voi...
  • z**8评论了:Scanner对象可...
  • z**8向课程作业中提交了代码
  • S**n完成了课程的作业
  • S**n完成了课程的作业
  • z**8添加了笔记:注意,将一个整数和字...
  • d**7在课程中提出了问题:打印出来的HTML必...
  • h**u在课程中提出了问题:是的我在英国,只能利...
  • 勺**5向课程作业中提交了代码
  • h**u向课程作业中提交了代码
  • h**u在课程作业中回复了老师:老师,请问以上 by...
  • 天码君回复了F**s在课程中的问题:欢迎来到天码营学习,...
  • x**3向课程作业中提交了代码
  • x**3在课程作业中回复了老师:这给地方我知道怎么...
  • w**3评论了z**o在课程中的作业:不是按作业要求实现的...
  • w**z向课程作业中提交了代码
  • S**n完成了课程的作业
  • d**7在课程中提出了问题:老师您看看这个错在哪...
  • l**m向课程作业中提交了代码
  • x**4向课程作业中提交了代码
  • S**n完成了课程的作业
  • d**7向课程作业中提交了代码
  • w**3评论了d**7在课程中的作业:不要写死了字符串,题...
  • S**n完成了课程的作业
  • w**z向课程作业中提交了代码
  • w**z向课程作业中提交了代码
  • l**m向课程作业中提交了代码
  • w**3评论了h**u在课程中的作业:一开始 在定义的时候...
  • w**3回复了l**n在课程中的问题:你安装的应该是最新版...
  • w**3回复了h**u在课程中的问题:已经在代码上回答你了...
  • w**3评论了h**u在课程中的作业:根据要求我们知道让我...
  • f**a添加了笔记:Q...
  • 天码君回复了h**u在课程中的问题:欢迎来到天码营学习,...
  • 勺**5向课程作业中提交了代码
  • w**3评论了h**u在课程中的作业:可能题目表述不清, ...
  • j**7向课程作业中提交了代码
  • w**3评论了h**u在课程中的作业:后面会讲到 循环 。...
  • z**8添加了笔记:=='和'!='作为...
  • 刘保方向课程作业中提交了代码
  • h**u添加了笔记:初学Java时我们的...
  • h**u添加了笔记:Scanner对象可...
  • d**7在课程中提出了问题:老师好,这是我的作业...
  • h**u在课程作业中回复了老师:老师你好,请问怎么强...
  • h**u在课程中提出了问题:老师你好,在这个例子...
  • 天码君回复了j**7在课程中的问题:欢迎来到天码营学习,...
  • w**3回复了h**u在课程中的问题:代码相关的问题,可以...
  • d**7在课程中提出了问题:public voi...
反馈意见