【ARM&Linux】守护进程

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


【简介】

                守护进程,也就是通常说的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. \n");
        exit(EXIT_FAILURE);
    }

    if(pid > 0)     //父进程
        exit(EXIT_SUCCESS);

    /*---------------------------------*/
    /* 可以通过if检测说明是在子进程中了     */
    /*---------------------------------*/

    setsid();       // 脱离终端控制
    chdir("/");     // 改变工作目录
    umask(0);       // 清除掩码

    for(i=0; i<MAXFILE; 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. \n");
            running = false;
            exit(EXIT_FAILURE);
        }
        cnt++;
        sprintf(buf, "write data %ld \n", cnt);
        write(fd, buf, strlen(buf));
        close(fd);
        sleep(2);
    }

    return 0;
}
/****************************************************************************************
* 文件名: mytype.h
* 创建者: Kun
* 联 系: [email protected]
* 简 介: 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 <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

// 信号使用相关头文件
#if USE_SIGNAL
#include <sys/signal.h>
#endif // USE_SIGNAL

// 有名信号量操作相关头文件
#if USE_SEMAPHORE
#include <sys/sem.h>
#include <sys/ipc.h>
#endif // USE_SEMAPHORE

// 无名信号量操作相关头文件
#if USE_SEMAPHORE_UNNAMED
    #include <semaphore.h>
#endif // USE_SEMAPHORE_UNNAMED

// 共享内存操作相关头文件
#if USE_SHARE_MEMORY
#include <sys/shm.h>
#endif // USE_SHARE_MEMORY

// 消息队列相关头文件
#if USE_MSG_QUEUE
    #if !USE_SEMAPHORE
        #include <sys/ipc.h>
    #endif
#include <sys/msg.h>
#endif // USE_MSG_QUEUE

// 系统调用式文件编程头文件
#include <fcntl.h>

// 该文件所定义的接口通常都是大量针对系统调用的封装,
// 如 fork、pipe 以及各种 I/O 原语(read、write、close 等等)。
#include <unistd.h>

// linux系统中类型定义相关头文件
#include <sys/types.h>

// 文件状态,是unix/linux系统定义文件状态所在的伪标准头文件。
#if USE_FILE_CTL
#include <sys/stat.h>
#endif // USE_FILE_CTL

// 时间编程相关头文件
#if USE_TIME
#include <sys/time.h>
#endif // USE_TIME


// 线程相关头文件
#if USE_THREAD
    #include <pthread.h>
#endif // USE_THREAD

// 网络编程相关头文件
#if USE_SOCKET
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
#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..

猜你喜欢

转载自blog.csdn.net/qq153471503/article/details/79330130