创建守护进程步骤与setsid()
原创:http://www.cnblogs.com/mickole/p/3188321.html
一,守护进程概述
Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。
守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户(root)权限运行,因为它们要使用特殊的端口(1-1024)或访问某些特殊的资源。
一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备stdout还是标准出错设备stderr的输出都需要特殊处理。
守护进程的名称通常以d结尾,比如sshd、xinetd、crond等
二,创建守护进程步骤
首先我们要了解一些基本概念:
进程组 :
- 每个进程也属于一个进程组
- 每个进程主都有一个进程组号,该号等于该进程组组长的PID号 .
- 一个进程只能为它自己或子进程设置进程组ID号
会话期:
会话期(session)是一个或多个进程组的集合。
setsid()函数可以建立一个对话期:
如果,调用setsid的进程不是一个进程组的组长,此函数创建一个新的会话期。
(1)此进程变成该对话期的首进程
(2)此进程变成一个新进程组的组长进程。
(3)此进程没有控制终端,如果在调用setsid前,该进程有控制终端,那么与该终端的联系被解除。 如果该进程是一个进程组的组长,此函数返回错误。
(4)为了保证这一点,我们先调用fork()然后exit(),此时只有子进程在运行
现在我们来给出创建守护进程所需步骤:
编写守护进程的一般步骤步骤:
(1)在父进程中执行fork并exit推出;
(2)在子进程中调用setsid函数创建新的会话;
(3)在子进程中调用chdir函数,让根目录 ”/” 成为子进程的工作目录;
(4)在子进程中调用umask函数,设置进程的umask为0;
(5)在子进程中关闭任何不需要的文件描述符
说明:
1. 在后台运行。
为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。
if(pid=fork())
exit(0);//是父进程,结束父进程,子进程继续
2. 脱离控制终端,登录会话和进程组
有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。
控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:
setsid();
说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
3. 禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
if(pid=fork())
exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
4. 关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:
for(i=0;i 关闭打开的文件描述符close(i);>
5. 改变当前工作目录
进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/")
6. 重设文件创建掩模
进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0);
7. 处理SIGCHLD信号
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。
signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。
创建守护进程步骤与setsid()的更多相关文章
- 创建守护进程步骤与setsid() -- linux deamon进程
原创:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且 ...
- linux 创建守护进程的相关知识
linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...
- linux创建守护进程
守护进程deamon 是一个后台进程,无需用户输入就能运行,用来在系统后台提供某种服务. 常见的守护进程有Wbe服务器.邮件服务器以及数据库服务器等等.守护进程不能控制终端,所以任何的输入和输出都需要 ...
- Python中创建守护进程
python 创建守护进程 python 的os.setdid()提供了类似linux c api的 setsid 也可以通过unix双fork创建守护进程. 几个相关的函数 os.umask(0) ...
- ASP.NET Core Linux下为 dotnet 创建守护进程(必备知识)
前言 在上篇文章中介绍了如何在 Docker 容器中部署我们的 asp.net core 应用程序,本篇主要是怎么样为我们在 Linux 或者 macOs 中部署的 dotnet 程序创建一个守护进程 ...
- ASP.ENT Core Linux 下 为 donet创建守护进程(转载)
原文地址:http://www.cnblogs.com/savorboard/p/dotnetcore-supervisor.html 前言 在上篇文章中介绍了如何在 Docker 容器中部署我们的 ...
- Supervisor 为服务创建守护进程
今天需要再服务上部署一个.net 方面的项目:当时开启服务的命令只能在前台执行:使用nohub CMD &等放在后台开启服务都会宕机:所以搜寻了Supervisor 这个解决办法,为服务创建守 ...
- 嵌入式Linux应用程序开发详解------(创建守护进程)
嵌入式Linux应用程序开发详解 华清远见 本文只是阅读文摘. 创建一个守护进程的步骤: 1.创建一个子进程,然后退出父进程: 2.在子进程中使用创建新会话---setsid(): 3.改变当前工作目 ...
- .NET Core 部署到CentOS–2.创建守护进程, 通过Nginx公网访问
继上一篇, 我们确定在内网可以通过 "http://localhost:5000",可以访问到站点后,接下来我们要配置"守护进程","Nginx公网8 ...
随机推荐
- iOS-NSBundle、NSArray、NSDictionay
NSBundle.NSArray.NSDictionay 读取plist文件 NSDictionary *dict= [NSDictionary dictionaryWithContentsOfFi ...
- 希望对自学的javascript新手有帮助
- Edit Delete Mysql的主从复制
参考博客 https://www.cnblogs.com/zhoujie/p/mysql1.html Mysql的主从复制至少是需要两个Mysql的服务,当然Mysql的服务是可以分布在不同的服务器上 ...
- Android之Systrace
1 简介 https://www.lizenghai.com/archives/26061.html 2 用法 用命令行启动Systrace抓取采样:<Capture a system trac ...
- Django简介 --Python Web
Python Web主流的三种框架:Django.Flask.Tornado,使用频度:Django>Flask>Tornado 一.设计模式 MVC:模型(Model).View(视图) ...
- MAVEN(二)
1.本地仓库?Maven到底有哪些仓库?它们什么关系? Maven仓库: 本地仓库路径配置: 包查找路径:本地——>私服——>中央仓库,然后将查找到的jar同步到私服——>本地仓库 ...
- Python 基础教程 | 菜鸟教程
https://www.runoob.com/python/python-install.html
- python中的 __inti__ 和 __new__ 方法的区别
这个要从Python的面向对象实例化的过程说起 类名() 之后,开辟一块内存空间,然后调用__init__把空间的内存地址作为self的参数传递到函数的内部,所有和self有关的参数,属性都会和sel ...
- 十三、GPIO子系统
由于之后的触摸屏驱动分析中使用到了GPIO子系统和i2c子系统,因此在分析触摸屏驱动之前我准备把这两个子系统进行简单分析. 之前我们使用GPIO引脚的方式并不是推荐的方式,当我们更改某一bit时,很有 ...
- 夯实基础:彻底搞清楚Cookie 和 Session 关系和区别(转)
原文地址:http://www.sohu.com/a/281228178_120047080 网络请求中的cookie与set-Cookie的交互模式和作用:https://my.oschina.ne ...