博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux中Daemon守护进程编程
阅读量:5023 次
发布时间:2019-06-12

本文共 2331 字,大约阅读时间需要 7 分钟。

 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。Linux系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务,例如,作业规划进程crond、打印进程lqd等(这里的结尾字母d就是Daemon的意思)。

      一般情况下守护进程可以通过以下几种方式产生:

1,在系统启动的时候由启动脚本启动,这些启动脚本通常放在/etc/rc.d目录下

2,利用inetd超级系统服务器启动,如telnet等

3,由cron定时启动以及在终端用nohup启动的进程也是守护进程  

     由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。

守护进程的变成要点:
1. 蔽一些有关控制终端操作的信号
   这是为了防止在守护进程还没悠运行之前,控制终端收到干扰推出或者挂起
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGHUP,SIG_IGN);
2. 在后台运行。

  为避免挂起控制终端而将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。

      if(pid=fork())
          exit(0);//是父进程,结束父进程,子进程继续
3. 脱离控制终端,登录会话和进程组
      进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:
    setsid()
4. 关闭打开的文件描述符

  进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:

  #define   NOFILE   256  ;//不同系统中不同数值
  for(i=0;i<NOFILE;i++)
         colse(i);
5. 改变当前工作目录
     进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/")
   chdir("/");
6. 重设文件创建掩模
    进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除0:
   umask(0);
7. 处理SIGCHLD(子进程退出信号)信号
   处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程 将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地 将SIGCHLD信号的操作设为SIG_IGN。

 signal(SIGCHLD,SIG_IGN);

下面给出一个例程

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
int init_daemon(const char *pname,int facility) { int pid; int i; /*忽略可能的终端信号*/ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGTSTP,SIG_IGN); signal(SIGHUP,SIG_IGN); //创建子进程,父进程推出 if( (pid=fork())) exit(EXIT_SUCCESS);//是父进程,结束父进程,子进程继续 else if(pid < 0) { perror("fork error!\n"); exit(EXIT_FAILURE); } setsid();//设置新会话组长,脱离终端 for(i=0;i

运行之后,使用                       tail -n 1   /var/log/message

就可以查看到日志信息了。

(清悠我心:http://hi.baidu.com/%C7%E5%D3%C6%CE%D2%D0%C4/blog/category/linux%D3%A6%D3%C3%B1%E0%B3%CC)

转载于:https://www.cnblogs.com/hnrainll/archive/2011/09/06/2168792.html

你可能感兴趣的文章
Jmeter性能测试 入门
查看>>
安卓动画有哪几种?他们的区别?
查看>>
Nodejs学习总结 -Express入门(一)
查看>>
web前端优化
查看>>
ssh 连接原理及ssh-keygen
查看>>
vs2013编译qt程序后中文出现乱码
查看>>
【转】IOS数据库操作SQLite3使用详解
查看>>
Android官方技术文档翻译——ApplicationId 与 PackageName
查看>>
设计网站大全
查看>>
JVM CUP占用率过高排除方法,windows环境
查看>>
【转】JAVA字符串格式化-String.format()的使用
查看>>
【转】ButterKnife基本使用--不错
查看>>
【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”...
查看>>
函数中关于const关键字使用的注意事项
查看>>
微信架构(转)
查看>>
Web项目中的路径问题
查看>>
js随机数的取整
查看>>
关于解析漏洞
查看>>
十大经典预测算法(六)---集成学习(模型融合算法)
查看>>
用php做一个简单的注册用户功能
查看>>