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”并没有被成功打印出来。

相关内容

热门资讯

最新技巧!aapoke辅助工具... 最新技巧!aapoke辅助工具存在(原来是真的有挂)详细软件辅助挂教程是一款可以让一直输的玩家,快速...
玩家必备教程!悠闲游戏模拟器,... 玩家必备教程!悠闲游戏模拟器,心悦踢坑系统如何能给好牌,微信小程序黑科技神器(详细教程)1、该软件可...
黑科技辅助挂!微扑克职业代打 ... 黑科技辅助挂!微扑克职业代打 (透视)原来真的有挂(详细计算辅助教程);亲真的是有正版授权,小编(透...
智能辅助!线上德州有后台操控(... 智能辅助!线上德州有后台操控(辅助挂)wepower有外挂(原来真的有挂)关于wepower的基本介...
今日公布!欢乐棋牌有外 挂(竟... 今日公布!欢乐棋牌有外 挂(竟然是真的有挂)详细ai辅助教程关于机制的,其中提到了后台系统,玩家获胜...
玩家交流!决胜麻将胡牌神器,浙... 玩家交流!决胜麻将胡牌神器,浙江游戏大厅有外挂么,广东雀神麻雀辅助器怎么下载(详细教程)1)浙江游戏...
智能辅助!wepkoe有外挂(... 智能辅助!wepkoe有外挂(辅助挂)wepower辅助器(的确是真的有挂),支持语音通讯、好友开房...
软件辅助挂!线上德州ai智能机... 软件辅助挂!线上德州ai智能机器人 (软件透明挂)确实是真的有挂(详细外 挂教程)是一款可以让一直输...
实测必看!大连乐达麻将可以设置... 实测必看!大连乐达麻将可以设置胜率吗,多乐跑胡子外挂展示,广东雀神麻雀辅助器怎么下载(详细教程)1、...
玩家必备攻略!微扑克有挂(的确... 玩家必备攻略!微扑克有挂(的确是真的有挂)详细德州辅助教程;是一种具有地方特色的麻将游戏,要想赢得游...