#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
/* 创建守护进程函数 */
int daemonize(){
int childpid, fd, fdtablesize;
int error, in, out;
/* 忽略终端I/O信号,STOP信号 */
signal(SIGTTOU, SIG_IGN); /* 后台进程写控制终端 */
signal(SIGTTIN, SIG_IGN); /* 后台进程读控制终端 */
signal(SIGTSTP, SIG_IGN); /* 终端挂起 */
signal(SIGHUP, SIG_IGN); /* 进程组长退出时向所有会议成员发出的 */
/* 父进程退出,子进程成为孤儿进程 */
if (fork()!=0)
exit(1);
/* 设置新会话的领头进程,并与原来的登录会话和进程组脱离 */
if (setsid() == -1)
exit(1);
/* 防止会话组长重新申请控制终端,子进程退出,孙进程没有控制终端了 */
if (fork()!=0)
exit(1);
/* 关闭打开的文件描述符,防止资源浪费和防止引起无法预料的错误 */
for (fd = 3, fdtablesize = getdtablesize();fd < fdtablesize;fd++){
close(fd);
}
/* 重定向标准输入/标准输出和标准错误输出 */
error = open("./stderr", O_WRONLY|O_CREAT|O_APPEND, 0600);
dup2(error, 2);
close(error);
in = open("./stdin", O_RDONLY|O_CREAT,0600);
dup2(in, 0);
close(in);
out = open("./stdout", O_WRONLY|O_CREAT|O_APPEND,0600);
dup2(out, 1);
close(out);
/* 可以改变工作目录 */
/* chdir("/"); */
/* 重设文件创建掩模 */
umask(0);
/* 忽略SIGCHLD信号, 防止僵尸进程 */
signal(SIGCHLD, SIG_IGN);
return 0;
}
/* 单实例实现, 成功返回0, 失败程序退出, 打印错误或已运行进程号 */
int already_running(const char *szLockFilePath){
int fd;
char szBuf[256] = { 0x00 }; fd = open(szLockFilePath, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd < 0){
memset(szBuf, 0x00, sizeof(szBuf));
sprintf(szBuf, "open LockFile failed!LockfilePath=[%s]/n", szLockFilePath);
perror(szBuf);
exit(1);
}
/* 尝试获取文件锁 */
struct flock fl;
memset(&fl, 0x00, sizeof(struct flock));
if (fcntl(fd, F_GETLK, &fl) < 0){
perror("fcntl get LockState failed!/n");
close(fd);
exit(1);
}
if (fl.l_type != F_UNLCK){
memset(szBuf, 0x00, sizeof(szBuf));
sprintf(szBuf, "已经有一个运行实例了。进程号为[%ld]/n", (long)fl.l_pid);
perror(szBuf);
close(fd);
exit(1);
}
fl.l_whence = SEEK_SET;/* 决定l_start的位置 */
fl.l_start = 0; /* 设置锁定区域开头位置 */
fl.l_len = 0; /* 设置锁定区域长度 */
fl.l_type = F_WRLCK;/* 设置锁定状态为写锁 */
fl.l_pid = getpid(); /* 设置锁进程号 */
/* 阻塞式加锁 */
if (fcntl(fd, F_SETLK, &fl) < 0){
perror("fcntl set Lockfile failed!/n");
close(fd);
exit(1);
}
/* 把进程号写入文件 */
ftruncate(fd, 0);
memset(szBuf, 0x00, sizeof(szBuf));
sprintf(szBuf, "%ld", (long)getpid());
write(fd, szBuf, strlen(szBuf)+1);
return 0;
}
int main(void){
time_t now;
daemonize();
already_running("./MyDaemon.pid");
openlog("MyMsgDaemon", LOG_CONS | LOG_PID, 0);
syslog(LOG_DEBUG, "守护进程测试/n");
while (1){
time(&now);
syslog(LOG_DEBUG, "守护进程测试, 当前时间:[%s]/n", ctime(&now));
sleep(6);
}
return 0;
}

UNIX环境高级编程——单实例的守护进程的更多相关文章

  1. UNIX环境高级编程 第13章 守护进程

    守护进程daemon是一种生存周期很长的进程.它们通常在系统引导时启动,在系统关闭时终止.守护进程是没有终端的,它们一直在后台运行. 守护进程的特征 在Linux系统中,可以通过命令 ps -efj ...

  2. 《UNIX环境高级编程》第七章进程环境

    7.2 main函数 1.C程序总是从main函数开始执行的,原型:int main(int argc,char *argv[]);argc是命令行参数的个数argc是指向参数的各个指针所构成的数组2 ...

  3. (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  4. Unix环境高级编程——守护进程记录总结(从基础到实现)

    一.概念及其特征 守护进程是系统中生存期较长的一种进程,常常在系统引导装入时启动,在系统关闭时终止,没有控制终端,在后台运行.守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程 ...

  5. Unix环境高级编程:守护进程

    参考 Unix环境高级编程,第9,13章 介绍 守护进程就是Linux中使用ps aux那些一般以d结尾的程序,比如rsyslogd,sshd等,为daemon简称.他们是长期在后台执行的随终端关闭而 ...

  6. Unix环境高级编程第三版中实例代码如何在自己的linux上运行的问题

    学习Linux已经有2个月了,最近被期末考试把进度耽误了,前几天把Unix环境高级编程看了两章,感觉对Linux的整体有了一些思路,今天尝试着对第一章涉及到的一个简单的交互式shell编译运行一下,结 ...

  7. 《UNIX环境高级编程(第3版)》

    <UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison ...

  8. (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  9. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

随机推荐

  1. bzoj 3277: 串

    Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中 至少k个字符串的子串(注意包括本身). Solution 出现 \(k ...

  2. [SPOJ 287] Smart Network Administrator 二分答案+网络流

    The citizens of a small village are tired of being the only inhabitants around without a connection ...

  3. UVA129 —— Krypton Factor (氪因素)

    Input and Output In order to provide the Quiz Master with a potentially unlimited source of question ...

  4. [POJ2406]字符串的幂

    题目描述] 对于给定的两个字符串a,b,我们定义a*b是将把它们连接在一起形成的字符串.例如,若a="abc",b="def",则a*b="abcde ...

  5. bzoj3129[Sdoi2013]方程 exlucas+容斥原理

    3129: [Sdoi2013]方程 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 582  Solved: 338[Submit][Status][ ...

  6. bzoj2005 NOI2010 方案统计

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 4387  Solved: 2619[Submit][Statu ...

  7. VM11 CentOS6.7 i386 安装 oracle 11g r2

    CentOS 6.7 i386:最小桌面版本--中文1.网络配置 ifup eht0 vim /etc/sysconfig/network-scripts/ifcfg-eth0 修改:NBOOT=ye ...

  8. RESTful Console Application

    RESTful Console Application Introduction Inspirited by RESTFul architecture, A console application t ...

  9. 关于一些基础的Java问题的解答(六)

    26. ThreadPool用法与优势 ThreadPool即线程池,它是JDK1.5引入的Concurrent包中用于处理并发编程的工具.使用线程池有如下好处: 降低资源消耗:通过重复利用已创建的线 ...

  10. python实现编写windows服务

    使用python编写windows服务 最近测试服务器上经常发生磁盘空间不足,每次手动清除比较麻烦,所以写个windows服务定时清理下.中间也遇到过几个坑,一起记录下来. 1.python实现win ...