zoukankan      html  css  js  c++  java
  • Linux C启动时创建pid文件

    程序在启动时将pid写入文件,当程序再次启动时会进行检测,避免启动多个实例。

    util-pidfile.h文件

    #ifndef __UTIL_PID_H__
    #define __UTIL_PID_H__
    
    int PidfileCreate(const char *);
    void PidfileRemove(const char *);
    int PidfileTestRunning(const char *pid_filename);
    
    #endif /* __UTIL_PID_H__ */
    

    util-pidfile.c文件

    #include <stdio.h>
    #include <inttypes.h>   // PRIuMAX
    #include <errno.h>      // errno
    #include <string.h>     // strerror
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h> // getpid
    #include <signal.h> // kill
    
    #include "util-debug.h"
    #include "util-pidfile.h"
    
    /**
     * \brief Write a pid file (used at the startup)
     *        This commonly needed by the init scripts
     *
     * \param pointer to the name of the pid file to write (optarg)
     *
     * \retval 0 if succes
     * \retval -1 on failure
     */
    int PidfileCreate(const char *pidfile)
    {
        int pidfd = 0;
        char val[16];
    
        int len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid());
        if (len <= 0) {
            LogError("Pid error (%s)", strerror(errno));
            return(-1);
        }
    
        pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
        if (pidfd < 0) {
            LogError("unable to set pidfile '%s': %s",
                       pidfile,
                       strerror(errno));
            return(-1);
        }
    
        ssize_t r = write(pidfd, val, (unsigned int)len);
        if (r == -1) {
            LogError("unable to write pidfile: %s", strerror(errno));
            close(pidfd);
            return(-1);
        } else if ((size_t)r != len) {
            LogError("unable to write pidfile: wrote"
                    " %"PRIdMAX" of %"PRIuMAX" bytes.", (intmax_t)r, (uintmax_t)len);
            close(pidfd);
            return(-1);
        }
    
        close(pidfd);
        return(0);
    }
    
    /**
     * \brief Remove the pid file (used at the startup)
     *
     * \param pointer to the name of the pid file to write (optarg)
     */
    void PidfileRemove(const char *pid_filename)
    {
        if (pid_filename != NULL) {
            /* we ignore the result, the user may have removed the file already. */
            (void)unlink(pid_filename);
        }
    }
    
    /**
     * \brief Check a pid file (used at the startup)
     *        This commonly needed by the init scripts
     *
     * \param pointer to the name of the pid file to write (optarg)
     *
     * \retval 0 if succes
     * \retval -1 on failure
     */
    int PidfileTestRunning(const char *pid_filename)
    {
        if (access(pid_filename, F_OK) == 0) {
            /* Check if the existing process is still alive. */
            pid_t pidv;
            FILE *pf;
    
            pf = fopen(pid_filename, "r");
            if (pf == NULL) {
                LogError("pid file '%s' exists and can not be read. Aborting!",
                        pid_filename);
                return -1;
            }
    
            if (fscanf(pf, "%d", &pidv) == 1 && kill(pidv, 0) == 0) {
                fclose(pf);
                LogError("pid file '%s' exists. Is program already running? Aborting!",
                        pid_filename);
                return -1;
            }
    
            fclose(pf);
        }
        return 0;
    }
    

    util-debug.h日志打印(主要是为了方便以后使用其他打印接口,就不用再修改util-pidfile.c文件了)

    #ifndef __UTIL_DEBUG_H__
    #define __UTIL_DEBUG_H__
    
    #ifndef LOG_PRINT
    #define LOG_MAX_LOG_MSG_LEN 2048
    #define Log(x, file, func, line, ...)                           \
        do {                                                        \
            char _log_msg[LOG_MAX_LOG_MSG_LEN];                     \
            snprintf(_log_msg, LOG_MAX_LOG_MSG_LEN, __VA_ARGS__);   \
            fprintf(stdout, "<%s> %s\n", x, _log_msg);              \
        } while(0)
    
    #define LogError(...) Log("ERROR", \
            __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
    
    #define LogWarning(...) Log("WARNING", \
            __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
    
    #define LogInfo(...) Log("INFO", \
            __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
    
    #define LogDebug(...) Log("DEBUG", \
            __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
    
    #define FatalError(...) do {                                           \
        LogError(__VA_ARGS__);                                             \
        exit(EXIT_FAILURE);                                                \
    } while(0)
    #endif
    
    #endif //__UTIL_DEBUG_H__
    

    main.c文件

    #include <stdio.h>
    #include <unistd.h>
    
    #include "util-pidfile.h"
    
    int main()
    {
        int result = 0;
    
        const char *pidfile = "/var/run/test_pid01.pid";
    
        if (PidfileTestRunning(pidfile) != 0)
            return -1;
    
        PidfileCreate(pidfile);
    
        while (1){
            sleep(1);
        }
    
        PidfileRemove(pidfile);
        return 0;
    }
    

    编译完成后运行该程序,然后再启动一个终端,再次运行这个程序的时候就会打印程序已运行并退出。

    <ERROR> pid file '/var/run/test_pid01.pid' exists. Is program already running? Aborting!
  • 相关阅读:
    【解决】Windows7任务栏输入法图标无法显示
    【解决】任务栏中找不到语言栏
    SQL Server中根据起始星期计算星期数和周次数的函数
    SharePoint 2010 中如何配置同步配置文件
    如何禁止Windows系统自动安装驱动
    [要点总结]SharePoint 2010:如何配置表单认证(FBA)
    【解决】如何升级网站集内容数据库
    [解决]Office 2010不能同步文件到SharePoint
    羽毛球比赛规则简略版
    [转]SharePoint 2013中如何恢复“用不同用户登录”链接
  • 原文地址:https://www.cnblogs.com/yanhai307/p/10511816.html
Copyright © 2011-2022 走看看