Linux并发程序设计(3):守护进程
创始人
2024-09-25 18:21:57
0

目录

前言

一、介绍

1.1 概念

1.2 特点

1.3 举例

二、系统编程

2.1 setsid函数

2.2 getpid函数

2.3 getsid函数

2.4 getpgid函数

2.5 chdir函数

三、代码例程

3.1 使子进程在后台运行

3.2 使子进程脱离原终端

3.3 更换目录,并设定权限(非必须)

3.4 关闭打开的文件描述符

3.5 完整代码 

3.6 代码实验 

总结


前言

本文介绍Linux系统中的三大进程类型之一——守护进程。

一、介绍

1.1 概念

守护进程又叫精灵进程(Daemon Process),它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。

其他相关概念:

  • 进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。
  • 会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。
  • 控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。

图1 进程、进程组和会话的示意图

1.2 特点

始终在后台运行,独立于任何终端,周期性的执行某种任务或等待处理特定事件。

它是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。

1.3 举例

http 服务的守护进程叫 httpd,mysql 服务的守护进程叫 mysqld。

更简便地创建守护进程: nohup 命令

nohup  xxxx  &

二、系统编程

2.1 setsid函数

pid_t setsid(void);

功能:子进程创建新会话 。

成功:返回调用进程的会话ID;失败:-1,设置errno。
调用了setsid函数的进程,既是新的会长,也是新的组长

2.2 getpid函数

pid_t getpid(void); 

功能:获取当前进程的pid。

2.3 getsid函数

pid_t getsid(pid_t pid)

功能:返回调用进程的会话ID

成功:返回调用进程的会话ID;失败:-1,设置errno

如若pid是0,getsid返回调用进程的会话ID;

如若pid并不属于调用者所在的会话,那么调用进程就不能得到该会话ID。

2.4 getpgid函数

pid_t getpgid(pid_t pid);

功能:获取指定进程(通过其进程标识符 pid)所属的进程组id

2.5 chdir函数

int chdir(const char * path); 

功能:将当前的工作目录改变成以参数路径所指的目录。

2.6 umask函数

mode_t umask(mode_t mask);

功能:umask()会将系统umask值设成(mode&~mask)的权限值。

例如:

在建立文件时指定文件权限为0666, 通常umask 值默认为022, 则该文件的真正权限则为0666&~022=0644, 也就是rw-r--r--返回值此调用不会有错误值返回. 返回值为原先系统的umask 值。

三、代码例程

3.1 使子进程在后台运行

  pid_t pid;   pid = fork();   if(pid<0){     perror("fork");     return 0;   }   else if(pid>0){     exit(0);   }   printf("I am a deamon\n");   printf("sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));

3.2 使子进程脱离原终端

if(setsid()<0){     perror("setsid");     exit(0); }   printf("after sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));

3.3 更换目录,并设定权限(非必须)

  chdir("/");    if(umask(0)<0){     perror("unmask");     exit(0);   }

3.4 关闭打开的文件描述符

已脱离终端,stdin / stdout / stderr无法再使用,故关闭当前的文件描述符。

  close(0);   close(1);   close(2);

3.5 完整代码 

#include  #include  #include  #include  int main(){   pid_t pid;   pid = fork();   if(pid<0){     perror("fork");     return 0;   }   else if(pid>0){     exit(0);   }   printf("I am a deamon\n");   printf("sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));    if(setsid()<0){     perror("setsid");     exit(0);   }      printf("after sid=%d,pid=%d,pgid=%d\n",getsid(getpid()),getpid(),getpgid(getpid()));   chdir("/");    if(umask(0)<0){     perror("unmask");     exit(0);   }      close(0);   close(1);   close(2);   printf("after close \n");      sleep(100);    return 0; } 

3.6 代码实验 

四、总结

从代码实验可以看出,我们以及成功的创建了守护进程,并且让它“当家做主人”,成为了会话的组长,同时我们也可以看到,因为关闭了打开的文件描述符,最后的“after close \n”并没有被成功打印出来。

相关内容

热门资讯

3分钟教程!丽水茶苑麻将辅助a... 3分钟教程!丽水茶苑麻将辅助app(辅助挂)详细教程(切实真的有挂);1、ai辅助优化,发牌逻辑科技...
透视脚本!aapoker透视怎... 透视脚本!aapoker透视怎么用(透视)ai插件(果然是有挂);1、下载好aapoker透视怎么用...
透视好牌!德普之星辅助器怎么用... 透视好牌!德普之星辅助器怎么用, (德普之星)本来是有挂(透视)私人局透视(有挂规律);1)德普之星...
透视辅助!wpk可以作弊吗,(... 透视辅助!wpk可以作弊吗,(WPK)竟然真的是有挂(透视)俱乐部辅助器(有挂详情)1)wpk可以作...
透视安装包!wepoker国外... 透视安装包!wepoker国外版透视,(WePoKer)原来有挂(透视)有透视方法(有挂黑科技)1、...
透视透视!约局吧德州可以透视吗... 透视透视!约局吧德州可以透视吗,werplan透视挂,插件教程(有挂教程)1、约局吧德州可以透视吗透...
一分钟教程!多乐微信小程序辅助... 一分钟教程!多乐微信小程序辅助器安装(辅助挂)详细教程(都是真的有挂)1、起透看视 透明视辅助2、随...
透视最新!aapoker发牌逻... 透视最新!aapoker发牌逻辑(透视)透视方法(本来存在有挂)该软件可以轻松地帮助玩家将aapok...
透视计算!德扑之心免费透视, ... 透视计算!德扑之心免费透视, (德扑之心)果然真的是有挂(透视)透视辅助(有挂解密);1、实时德扑之...
透视辅助工具!wepoker辅... 透视辅助工具!wepoker辅助插件功能,(WePoKer)切实真的有挂(透视)辅助器(有挂脚本)1...