【ARM&Linux】守护进程

2019-07-12 18:37发布

class="markdown_views prism-atelier-sulphurpool-light">

《守护进程代码编程模型》


【简介】

        守护进程,也就是通常说的Daemon(精灵)进程,是Linux中的一种服务进程。
 
特点:
1. 后台运行
2. 独立于控制终端
3. 不受父进程的影响

【编程模型】

  1. 保证是在后台运行
  2. 保证独立于终端
  3. 保证不受父进程的影响
    3.1:修改工作目录。(进程假如在U盘目录启动,如果进程不结束,则U盘就会卸载不掉,所以需要修改目录,摆脱父进程目录的影响)。
    3.2:重设文件权限掩码。
    3.3:关闭文件描述符。(用于释放主进程打开的资源,这些资源大多数在守护进程中用不到,及时用到在open就是了。)

【代码示例】

实现功能:
    建一个守护进程,在后台中,不断往/home/kun/tmp.txt 中写入。
代码
/**************************************************************************************** * 文件名: daemon.c * 创建者: * 时 间: * 联 系: * 简 介: 守护进程编程示例。 *****************************************************************************************/ /*********************************************************** 守护进程特点: 1、后台运行 2、独立于控制终端 3、不受父进程的影响 使用说明: 创建子进程,用不受终端控制和主进程控制的子进程来当做守护进程 ************************************************************/ #include "mytype.h" #define MAXFILE 65535 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; } /**************************************************************************************** * 文件名: mytype.h * 创建者: Kun * 联 系: 153471503@qq.com * 简 介: linux常用类型定义 * 最后修改时间: 2018/2/15 17:57 *****************************************************************************************/ #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 //-------------------------------< end ----------------------------// //---------------------------< includes >---------------------------// // c标准库头文件 #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 // 该文件所定义的接口通常都是大量针对系统调用的封装, // 如 fork、pipe 以及各种 I/O 原语(read、write、close 等等)。 #include // linux系统中类型定义相关头文件 #include // 文件状态,是unix/linux系统定义文件状态所在的伪标准头文件。 #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 //-------------------------< includes end >-------------------------// // bool类型定义 #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 //tcp客户端使用封装结构 typedef struct use_tcp_client{ int fd; struct sockaddr_in server_addr; socklen_t addr_length; }USE_TCP_CLIENT; //tcp服务端使用结构封装 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..