class="markdown_views prism-atelier-sulphurpool-light">
《守护进程代码编程模型》
【简介】
守护进程,也就是通常说的Daemon(精灵)进程,是Linux中的一种服务进程。
特点:
1. 后台运行
2. 独立于控制终端
3. 不受父进程的影响
【编程模型】
- 保证是在后台运行
- 保证独立于终端
- 保证不受父进程的影响
3.1:修改工作目录。(进程假如在U盘目录启动,如果进程不结束,则U盘就会卸载不掉,所以需要修改目录,摆脱父进程目录的影响)。
3.2:重设文件权限掩码。
3.3:关闭文件描述符。(用于释放主进程打开的资源,这些资源大多数在守护进程中用不到,及时用到在open就是了。)
【代码示例】
实现功能:
建一个守护进程,在后台中,不断往/home/kun/tmp.txt 中写入。
代码
/****************************************************************************************
* 文件名: daemon.c
* 创建者:
* 时 间:
* 联 系:
* 简 介: 守护进程编程示例。
*****************************************************************************************/
/***********************************************************
守护进程特点:
1、后台运行
2、独立于控制终端
3、不受父进程的影响
使用说明:
创建子进程,用不受终端控制和主进程控制的子进程来当做守护进程
************************************************************/
int main()
{
pid_t pid;
int fd;
int i;
char buf[64];
unsigned long cnt=0;
bool running = true;
// 1、创建子进程
pid = fork();
if(pid < 0) //创建失败
{
DEBUG_ERROR("fork err.
");
exit(EXIT_FAILURE);
}
if(pid > 0) //父进程
exit(EXIT_SUCCESS);
/*---------------------------------*/
/* 可以通过if检测说明是在子进程中了 */
/*---------------------------------*/
setsid(); // 脱离终端控制
chdir("/"); // 改变工作目录
umask(0); // 清除掩码
for(i=0; i
{
close(i);
}
memset(buf, 0, sizeof(buf));
while(running)
{
if( (running) && ((fd=open("/home/kun/tmp.txt", O_CREAT|O_APPEND|O_WRONLY, 0666))<0) )
{
DEBUG_ERROR("open file err.
");
running = false;
exit(EXIT_FAILURE);
}
cnt++;
sprintf(buf, "write data %ld
", cnt);
write(fd, buf, strlen(buf));
close(fd);
sleep(2);
}
return 0;
}
#ifndef _MYTYPE_H_
#define _MYTYPE_H_
#define USE_TIME 0
#define USE_SIGNAL 0
#define USE_SHARE_MEMORY 0
#define USE_SEMAPHORE_NAME 0
#define USE_SEMAPHORE_UNNAMED 0
#define USE_MSG_QUEUE 0
#define USE_FILE_CTL 1
#define USE_THREAD 0
#define USE_SOCKET 0
#include
#include
#include
#include
#include
#if USE_SIGNAL
#include
#endif // USE_SIGNAL
#if USE_SEMAPHORE
#include
#include
#endif // USE_SEMAPHORE
#if USE_SEMAPHORE_UNNAMED
#include
#endif // USE_SEMAPHORE_UNNAMED
#if USE_SHARE_MEMORY
#include
#endif // USE_SHARE_MEMORY
#if USE_MSG_QUEUE
#if !USE_SEMAPHORE
#include
#endif
#include
#endif // USE_MSG_QUEUE
#include
#include
#include
#if USE_FILE_CTL
#include
#endif // USE_FILE_CTL
#if USE_TIME
#include
#endif // USE_TIME
#if USE_THREAD
#include
#endif // USE_THREAD
#if USE_SOCKET
#include
#include
#include
#endif // USE_SEMAPHORE_NAME
#ifndef bool
typedef unsigned int bool;
#endif
enum
{
true = 1,
false = !true
};
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
#define DEBUG_INFO(...) printf("Info: "); printf(__VA_ARGS__)
#define DEBUG_ERROR(...) printf("Error: "); printf(__VA_ARGS__)
#define DEBUG_WARNING(...) printf("Warning: "); printf(__VA_ARGS__)
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
#if USE_SEMAPHORE
typedef struct sem_use SEM_USE;
struct sem_use
{
int semid;
key_t key;
struct sembuf sops;
};
#endif // USE_SEMAPHORE
#if USE_SHARE_MEMORY
typedef struct shmem_use SHMEM_USE;
struct shmem_use
{
int shmid;
key_t key;
};
#define BUF_SIZE 1024*1 //共享内存大小
typedef struct shmem_area SHMEM_AREA;
struct shmem_area
{
bool isnull;
char data[BUF_SIZE];
};
#endif // USE_SHARE_MEMORY
#if USE_MSG_QUEUE
typedef struct msg_queue_use MSG_QUEUE_USE;
struct msg_queue_use{
key_t key;
int msgid;
};
#endif // USE_MSG_QUEUE
#if USE_SOCKET
typedef struct use_tcp_client{
int fd;
struct sockaddr_in server_addr;
socklen_t addr_length;
}USE_TCP_CLIENT;
typedef struct use_tcp_service{
int fd;
int newfd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
socklen_t addr_length;
}USE_TCP_SERVICE;
#endif // USE_SOCKET
#endif // _TYPE_H_
【运行结果】
end..