[Linux]守护进程(精灵进程)

一、守护进程是什么

守护进程是生存期很长的一种进程,可以说它是7*24小时工作的。(什么是7*24,一周7天,每天24小时,这不就是一年365天一直在工作嘛,还搞的这么诙谐,哈哈)。它们常常在系统引导装入时启动,仅在系统关闭时才终止。因为它们没有控制终端,所以说它们是在后台运行的,而且它没法直接和用户交互。当然在后台运行的可不一定是守护进程哦。Unix下有很多守护进程,执行日常事务。守护进程是一种很有用的进程,Linux下的很多服务器大多是用守护进程实现的。比如Internet服务器inetd,Web服务器httpd等。

守护进程还有一个特点:其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着。

我们用ps -axj来查看系统中的进程。-a显示由其他用户所拥有的进程的状态,-x显示没有控制终端的进程,-j显示与作业有关的信息(进程组ID,会话ID,控制终端,终端进程组ID)。守护进程通常以d为结尾。

这里写图片描述

由上述的进程中,TPGID为-1的都是没有控制终端的进程,也是守护进程。还有像COMMAND那一列中,用[]括起来的进程名,都表示内核线程。这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,以k开头,表示Kernel。它自成进程组,自成会话。

进程1通常是init,它是一个系统守护进程。

二、创建守护进程

我们写一个mydaemon:

步骤哈:1.创建守护进程首先得,调用umask来将文件模式创建屏蔽字设置为0。

2.调用fork,使父进程退出。因为在这里,后面使用setid不允许进程为进程组id,因此得先将父进程exit。

3.调用setid创建一个新会话,成为会话首进程,成为进程组组长,没有控制终端。这就是守护进程的特点吧。

4.将当前的工作目录改为根目录。你想想,如果你将守护进程的工作目录设置为当前工作目录而非根目录,那么如果将这个目录删除后,就会导致严重的丢失问题。你的那个目录将不能被删除。

5.关闭不再需要的文件描述符。

守护进程实现:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
void mydaemon()
{umask(0);if(fork() <=  0)//child{}else//father{exit(0);}setsid();signal(SIGCHLD,SIG_IGN);close(0);close(1);close(2);chdir("/");}int main()
{mydaemon();
//  daemon(0,0);while(1);return 0;
}

运行结果:

这里写图片描述

这样一个守护进程就写好啦。当然库里边也实现了一个守护进程,daemon函数。

int daemon(int nochdir, int noclose);

这里nochdir表示不改变当前守护进程的目录,noclose表示不关闭进程文件描述符。

当前我们是把工作目录修改了,所以:

这里写图片描述

当我们都设置为0时,daemon(0,0);说明修改; 当我们都设置为1时,daemon(1,1);说明不修改;

三、为什么创建守护进程时有人fork两次?

第二次fork的作用:虽然当前关闭了和终端的联系,但是后期可能会误操作打开了终端。只有会话首进程能打开终端设备,也就是再fork一次,再把父进程退出,再次fork的子进程作为守护进程继续运行,保证了该精灵进程不是会话的首进程,第二次不是必须的,是可选的,市面上有些开源项目也是fork一次。(再次fork一次,保证daemon进程,之后不会打开tty设备)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux命令行界面下ctrl 常用组合键速查表

Ctrlz 暂停正在运行的程序 Ctrll 清屏 Ctrld 结束输入或退出shell Ctrla 切换到命令行开始 Ctrle 切换到命令行末尾 Ctrlu 删除光标前内容 Ctrlk 删除光标后内容 Ctrlxu 撤销操作

[Linux]运输层的端口

既然提到端口&#xff0c;我们就来分析一下为什么要使用端口的缘由吧。我们首先要知道的是&#xff0c;运输层有复用和分用的功能。应用层所有的应用进程都可以通过运输层再传送到IP层&#xff0c;这就是复用。运输层从IP层收到数据后必须交付到指明的应用进程&#xff0c;这就…

浅谈shell中的clear命令实现

NAME(名称) clear - 清除终端屏幕 SYNOPSIS(总览) clear DESCRIPTION(描述) clear可以在允许的情况下清屏. 它会在环境变量中查找终端的类型, 然后到terminfo数据库中找出清屏的方法. 《man手册》 #include <stdio.h>int clear_main(int argc, char **argv) {/* Th…

C++ 对引用的理解

引用可以看做是数据的一个别名&#xff0c;通过这个别名和原来的名字都能够找到这份数据引用必须在定义的同时初始化&#xff0c;并且以后也要从一而终&#xff0c;不能再引用其它数据&#xff0c;这有点类似于常量&#xff08;const 变量&#xff09;。引用变量 里面 实际存储…

[Linux]ARP协议

概念&#xff1a; 1. ARP协议(地址解析协议):由IP地址转换为MAC地址的协议。IP地址&#xff1a;网络号主机号。MAC地址&#xff1a;数据链路层的物理地址&#xff08;硬件地址&#xff09;。IP协议使用了ARP协议&#xff0c;因此被划归为网络层&#xff0c;但其用途是从网络层…

Makefile使用及多文件gdb 调试

文件内容 [koulocalhost makefile]$ cat 1.c #include "3.h" int main() {key_t key ftok(".",1);printf("%d\n",add(1,2));return 0; }[koulocalhost makefile]$ cat 2.c #include "3.h" int add(int a, int b) {return a b; } [k…

C++ 对引用的理解2

1.指针就是数据或代码在内存中的地址&#xff0c;指针变量指向的就是内存中的数据或代码。这里有一个关键词需要强调&#xff0c;就是内存&#xff0c;指针只能指向内存&#xff0c;不能指向寄存器或者硬盘&#xff0c;因为寄存器和硬盘没法寻址。 2.其实 C 代码中的大部分内容…

Ubuntu各版本主要差异

Ubuntu各版本主要差异 (重定向自Ubuntu &#xff0c; kubuntu与xubuntu的差别 ) Ubuntu官方考虑到使用者的不同需求&#xff0c;提供各种不同的发行版。这几种发行版本的差别在于桌面环境和预设安装的软体不同&#xff0c;但套件库是采用一样的&#xff0c;所以您当然可以在安…

[Linux]CRC校验

CRC(Cyclic Redundancy Check),循环冗余校验码&#xff0c;是数据通信领域中最常用的一种差错校验码&#xff0c;其特征是信息字段和校验字段的长度可以任意选定。 CRC校验步骤&#xff1a; CRC分为两部分&#xff0c;前部分为信息码&#xff0c;后部分为校验码&#xff1b;设…

visual studio 2015 配置好qt5后, 第一次运行出现 无法打开源文件“QtWidgets/QApplication”和无法运行rc.exe的解决方案

无法打开源文件“QtWidgets/QApplication” a.在工程中右击项目&#xff0c;点击属性。 b.选择VC目录->包含目录 c.选择Qt安装目录中的头文件包含目录&#xff0c;一般为Qt版本号/版本号/编译器名/include 比如&#xff1a;E:\Qt\Qt5.6.3\5.6.3\msvc2015\include 在C\C>附…

怎么在vs中查看一个数组的所有元素

在监视窗口&#xff0c;我们想要查看所有的数组元素。 这个时候 int arr[] {1,2,3} arr只显示1 正确的方法 arr&#xff0c;10

[Linux]NAT和代理服务器

1. NAT&#xff1a;&#xff08;Network Address Translation&#xff09;是网络地址转换。 我们有这样一种场景&#xff0c;在专用网内部的一些主机本来已经分配到了本地IP地址&#xff0c;但现在又想和因特网上的主机通信&#xff0c;我们可以设法再申请一些全球IP地址&…

使用 C++的第三方库 jsoncpp的步骤以及出现的问题

Jsoncpp 是一个json解析库 下载地址为&#xff1a; http://sourceforge.net/projects/jsoncpp/ 方法一&#xff1a;使用Jsoncpp生成的lib文件 解压上面下载的Jsoncpp文件&#xff0c;在jsoncpp-src-0.5.0/makefiles/vs71目录里找到jsoncpp.sln&#xff0c;用VS2008版本编译&am…

常用的友元重载运算符OSTREAM

对<<运算符重载&#xff0c;让他能和cout一起显示对象内容。 显示值可以使用show()&#xff0c;但是使用cout<<更方便。 ostream类对该运算符进行了重载&#xff0c;将其转换成输出工具。 cout就是一个ostream的对象&#xff0c;他可以自动识别所有的c基本类型。…

python字符串系列

1.find方法用于在长串中查找子串&#xff0c;返回子串中最左位置的下标&#xff0c;如果没找到&#xff0c;则返回-1 2.join方法用于在队列中添加元素 3.lower返回字符串的小写字母版 4.replace返回字符串中所有匹配项均被替换之后得到字符串 5.split将字符串分割成序列 6.stri…

C++ wstring 与 string 之间的相互转换.

方式一&#xff1a;调用Windows API #include <Windows.h> //将string转换成wstring wstring string2wstring(string str) { wstring result; //获取缓冲区大小&#xff0c;并申请空间&#xff0c;缓冲区大小按字符计算 int len MultiByteToWideChar(CP_ACP, 0,…

linux网络编程Internet Socket地址,套接字,和函数

文章内容节选《linux/UNIX 系统网络编程》 Internet domain socket地址有两种&#xff1a;IPv4 IPv6 IPv4被存储在结构体中&#xff0c; 该结构体在 netinet/in.h 中进行定义 cd usr/include/netinet/in.h struct in_addr {in_addr_t s_addr; //32位IPv4地址 }struct so…

浅谈socket网络编程函数参数(一)

socket函数解析 概念: 每个进程的进程空间里都有一个socket描述符表。套接字描述符表属于一个进程&#xff0c;而socket地址结构位于操作系统的内核缓冲。 函数原型 #include <sys/socket.h>int socket(int domain, int type, int protocol);函数参数 family参数 默…

C++ const 与 extern

C语言中&#xff0c; const修饰的全局变量是外部链接属性&#xff0c;比如在 a.c文件中有 const int m_a 10; 在b.c中想用这个全局变量&#xff0c; 在b.c中这样 extern const int m_a; 就可以使用a.c中的m_a C 语言中&#xff0c; const修饰的全局变量是内部链接属性&#x…

浅谈socket网络编程函数参数(二)

bind()函数 bind()函数把一个地址族中的特定地址赋给socket。 例如对应AF_INET、AF_INET6就是把一个ipv4或ipv6地址和端口号组合赋给socket。 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数解析 sockfd&#xff1a;即socket描述字&#xff0c…