1、守护进程概述

守护进程就是通常所说的daemon进程,他是linux中的后台服务进程。他是一个生存期很长的进程,通常独立于控制终端并且周期性的执行某种任务,或等待处理魔种发生的事件。守护进程通常在系统开机启动时开始执行,在系统关闭时终止。linux中很多服务器都是通过守护进程实现的。

由于在linux中,每一个系统与用户进行交流的界面成称为终端。每一个从终端开始执行的进程都会依赖于终端,这个终端称为这些进程的终端。当控制终端关闭时,相应的进程都会自动结束。但是守护进程能够突破这种限制,不受终端关闭的影响。反之,如果希望某个进程不因为用户、终端或者其他的变化而受影响,那么就必须把这给进程变成守护进程。

2、编写守护进程

编写守护进程看似复杂,但实际上也是遵循一个特定的流程的。就分5个步骤来讲解怎么创建一个简单守护进程。在讲解的同时,也会同时介绍与创建守护进程相关的概念与函数。

(1)创建子进程,父进程推出

这是编写守护进程的第一步。由于守护进程时脱离控制终端的,因此完成第一部后子进程变成后台进程,就给用户程序已经运行完毕的感觉。只有的所有工作都在子进程中完成,而用户可以通过shell执行其他的命令,从而在形式上做到了与控制端的脱离。到这里父进程推出之后,子进程就会称成为一个孤儿进程,在linux中当系统发现一个孤儿进程,就会由1号进程(也就是init进程)收养它,这样,原来的进程就会变成init进程的子进程了。其实现代码如下:

pid = fork;
if(pid > 0)
{exit(0);    //    父进程退出
}

(2)在子进程中创建会话

这个步骤时创建子进程中最重要的一步,虽然他的实现非常简单,但它的意义却非常重大。在这里使用的函数时setsid()。在介绍setsid之前,要了解两个概念:进程组和会话期。

进程组:进程组时一个或多个进程的集合。进程组由进程ID来唯一标识。处理进程组(PID)之外,进程组ID也是进程的必备属性。每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID。且进程组ID不会因为组长的推出而受影响。

会话期:会话组是一个或多个进程组的集合。通常一个会话开始于用户的登陆,终止与用户退出;或者开始于终端打开,结束于终端关闭。会话期的第一个进程称为会话组长。在此期间该用户运行的所有进程都属于这个会话期。

接下来具体介绍setsid()的相关内容。

setsid函数的作用:用于创建一个新会话,并且担任该会话的组长。

  • 让进程摆脱原会话的控制
  • 让进程摆脱原进程组的控制
  • 让进程摆脱原控制端的控制

在父进程调用fork函数时,子进程全盘复制了父进程的会话期、进程组、控制端等。虽然父进程推出了,但原先的会话期、进程组、控制终端并没有改变,因此这不是真正意义上的独立,而setsid函数能够使进程完全独立出来,从而摆脱所有进程的控制。

(2)setsid函数格式

所需头文件

#include <unistd.h>

#include <sys/types.h>

函数原型 pid_t setsid(void);
函数返回值

成功:进程组ID

出错:-1

(3)改变当前目录

这一步也是必要的步骤。使用fork函数创建的子进程继承了父进程的当前工作目录。由于在进程运行过程中,当前目录所在的文件系统(比如“/mnt/usb”等)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常做法就是让“/”作为守护进程的当前工作目录,这样就可以避免上述的问题。当然,如有特殊需要,也可以将当前工作目录换作其他的工作路径,如“/tmp”。改变工作目录的函数就是chdir();

(4)重设文件权限掩码

文件权限掩码(通常用8进制表示)的作用是屏蔽文件权限中的对应位。例如,如果文件权限掩码是050,他表示屏蔽文件组拥有者的可读与可执行权限。有使用fork函数创建的子进程继承了父进程的文件权限掩码,这就给子进程使用文件带来了一定的麻烦。因此将文件权限掩码设置为0,可以增强该守护进程的灵活性。设置文件权限掩码的函数是umask()。在这里通常使用方法是umask(0)。

(5)关闭文件描述符

同文件权限掩码一样,用fork函数新创建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不可能被守护进程访问,但他们一样占用系统资源,而且还可能导致所在的文件系统无法被卸载。特别是守护进程与终端无关的,所以指向终端设备标准输入、标准输出和标准错误流已经失去了存在的价值,应当被关闭。通常按照下面的方式关闭文件描述符。

int num;
num = getdtablesize();    //获取当前进程文件描述符表大小
for(i = 0; i < num; i++)
{close(i);
}

这样一个简单的守护进程就建立起来了。

下面实现一个守护进程的完整实例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main(int argc, char **argv)
{pid_t pid;int i, fd;pid = fork();     //第一步if(pid < 0){printf("Error fork\n");exit(1);}else if(pid > 0){exit(0);  //父进程退出}setsid();       //第二步chdir("/tmp");   //第三步umask(0);      //第四步for(i = 0; i < getbtablesize(); i++) //第五步{close(i);}/*下面开始守护进程的工作,一般都是一个死循环程序*/while(1){}exit(0)
}

Linux中编写简单的守护进程相关推荐

  1. Linux中的两种守护进程stand alone和xinetd

    Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...

  2. Linux守护进程service Daemon 【C语言构建简单的守护进程】

    Linux Daemon Writing HOWTO 这里视频讲的很清楚 牛客网-c/C++Linux课程-守护进程 int main() {// 1.创建子进程,退出父进程pid_t pid = f ...

  3. 创建一个简单的守护进程

    下面的内容是看了书上总结来的. 要写这样的一个程序看似复杂,但是它也是遵循一定的规则的.书中的方法介绍了用五个步骤来创建一个简单的守护进程. 1.创建子进程,父进程退出 由于守护进程是在后台运行,脱离 ...

  4. linux命令行运行c程序,如何在Linux中编写和运行C程序

    Linux正在成为开发人员的编程天堂,成为开源和免费操作系统. Turbo C编译器已经是一种编译程序的旧方法,所以让程序员转向Linux以获得新的编程环境. 在本文中,我们将解释如何编写,编译和运行 ...

  5. 在Linux 中编写并运行C语言

    在Linux 中编写并运行C语言 流程 后续 流程 首先我们创建一个C语言文件 vim 1.c 我们进行相关程序的编写(我们以简单的输入输出为例) #include <stdio.h> i ...

  6. 在ubuntu linux 中编写一个自己的bash脚本

    在ubuntu linux 中编写一个自己的简单的bash脚本. 实现功能:终端中输入简单的命令(以pm为例(play music)),来实现音乐的播放.注:本人ununut中安装了audacious ...

  7. python使用spark_如何在Python中编写简单代码,并且速度超越Spark?

    全文共3482字,预计学习时长7分钟 如今,大家都在Python工具(pandas和Scikit-learn)的简洁性.Spark和Hadoop的可扩展性以及Kubernetes的操作就绪之间做选择. ...

  8. python 字节流分段_如何在Python中编写简单代码,并且速度超越Spark?

    全文共 3482字,预计学习时长 7分钟 如今,大家都在Python工具(pandas和Scikit-learn)的简洁性.Spark和Hadoop的可扩展性以及Kubernetes的操作就绪之间做选 ...

  9. Linux中的各种栈:进程栈 线程栈 内核栈 中断栈

    Linux中的各种栈:进程栈 线程栈 内核栈 中断栈 栈的作用 1. 函数调用 2. 多任务支持 Linux 中有几种栈?各种栈的内存位置? 1. 进程栈 2. 线程栈 3. 进程内核栈 4. 中断栈 ...

最新文章

  1. CSS实现跨浏览器兼容性的盒阴影效果
  2. 20年资深Oracle数据库专家:国内应用级DBA的缺失
  3. 始终在新标签页中打开文件
  4. Linux centos7安装nfs及服务端配置
  5. Resharper4.5:增强你的.net开发
  6. 前端学习(2930):内嵌改变样式
  7. 微信公众号关注用户的信息拉取
  8. 谷歌浏览器怎么登录及开启同步功能
  9. 《手把手教你学DSP》总结1
  10. VirtualBox中虚拟机IP地址相同
  11. Yourkit 监控Jetty(stand-alone)
  12. 006 研究生学信网的电子注册备案表在哪里弄
  13. 联通云OSS上传文件
  14. Array 属性和方法
  15. 入过滤(Ingress Filtering)
  16. 非标资产与标准资产_标准资产更新! 第二部分
  17. 1001 害死人不偿命的(3n+1)猜想 (15分)_Quentin
  18. 安卓打开rpm文件_android打开文件及打开方式(打开程序列表) | 学步园
  19. 福昕阅读器中,如何令两个pdf文件分别在两个不同的窗口显示?
  20. jsMath对象中的三角函数

热门文章

  1. 电大网络计算机考模块文字处理,2017电大计算机应用基础网考文字处理.doc
  2. 记忆网络之Hierarchical Memory Networks(架构分层)
  3. win8电脑关机的快捷键
  4. 基于阿里云物联网的无人值守远程农业智慧盒DIY之(一)总体设计
  5. 用RadioButton实现选择男女
  6. latex中如何设置页边距和页眉页脚?
  7. 绝对经典:最幽默的小笑话
  8. 企业都能用到的免费自动IT资产管理软件系统
  9. VUE开发中/deep/的使用 其他写法v-deep:: vue3中写法 :deep(.img)
  10. 说透中台上 中台的概念和种类