前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >UNIX(进程间通信):05---守护进程

UNIX(进程间通信):05---守护进程

作者头像
用户3479834
发布2021-03-04 14:38:52
7470
发布2021-03-04 14:38:52
举报
文章被收录于专栏:游戏开发司机游戏开发司机

守护进程是在后台运行不受终端控制的进程(如输入、输出等),一般的网络服务都是以守护进程的方式运行。守护进程脱离终端的主要原因有两点:(1)用来启动守护进程的终端在启动守护进程之后,需要执行其他任务。(2)(如其他用户登录该终端后,以前的守护进程的错误信息不应出现)由终端上的一些键所产生的信号(如中断信号),不应对以前从该终端上启动的任何守护进程造成影响。要注意守护进程与后台运行程序(即加&启动的程序)的区别。

创建守护进程的过程:

  1. fork子进程, 父进程退出, 所有工作在子进程中进行形式上脱离了控制终端; 必须
  2. 子进程创建新会话, setsid函数, 使子进程完全独立出来, 脱离控制; 必须
  3. 改变当前目录为根目录, chdir()函数, 防止占用可卸载的文件系统, 也可以换成其它路径, 为了增强程序的健壮性; 非必须
  4. 重设文件权限掩码, umask()函数, 防止继承的文件创建屏蔽字拒绝某些权限, 增加守护进程灵活性; 非必须
  5. 关闭文件描述符, 继承的打开文件不会用到, 浪费系统资源, 无法卸载, close(0), close(1), close(2); 非必须
  6. 执行核心工作
  7. 守护进程退出处理程序模型;
代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>

int main(int argc, const char * argv[]) {
    // 创建一个会话
    // 将子进程变为会长
    pid_t pid = fork();
    if (pid > 0) {
        exit(1);
        kill(getpid(), SIGKILL);
        raise(SIGKILL);
        abort();
    }
    else if (pid == 0) {
        // 变为会长
        // 会长变为守护进程
        setsid();
        while (1);
    }
    return 0;
}

我们也可以通过daemon函数来创建守护进程。

Daemon函数的用法

原型:

代码语言:javascript
复制
#include <unistd.h>  
int daemon(int nochdir, int noclose);

参数:

当 nochdir为零时,当前目录变为根目录,否则不变;

当 noclose为零时,标准输入、标准输出和错误输出重导向为/dev/null,也就是不输出任何信 息,否则照样输出。

返回值:

deamon()调用了fork(),如果fork成功,那么父进程就调用_exit(2)退出,所以看到的错误信息 全部是子进程产生的。如果成功函数返回0,否则返回-1并设置errno。

示例:

view plai

代码语言:javascript
复制
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <limits.h>  
  
int main(int argc, char *argv[])  
{  
    char strCurPath[PATH_MAX];  
  
    if(daemon(1, 1) < 0)  
    {  
        perror("error daemon.../n");  
        exit(1);  
    }  
    sleep(10);  
  
    if(getcwd(strCurPath, PATH_MAX) == NULL)  
    {  
        perror("error getcwd");  
        exit(1);  
    }  
    printf("%s/n", strCurPath);  
    return 0;  
}   

假如运行成功,父进程在daemon函数运行完毕后自杀,以后的休眠和打印全部是子进程来运行。

可以修改daemon函数的参数来查看效果。

可以去掉daemon一句,用./a.out&来验证效果。

当然在linux环境下你也可以使用nohup ./a.out &来把a.out作为一个后台执行的服务,将后台执行的一些控制台输出重定向到nohup.out文件中。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 游戏开发司机 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档