程序在启动时将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 = ;
char val[]; int len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid());
if (len <= ) {
LogError("Pid error (%s)", strerror(errno));
return(-);
} pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, );
if (pidfd < ) {
LogError("unable to set pidfile '%s': %s",
pidfile,
strerror(errno));
return(-);
} ssize_t r = write(pidfd, val, (unsigned int)len);
if (r == -) {
LogError("unable to write pidfile: %s", strerror(errno));
close(pidfd);
return(-);
} 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(-);
} close(pidfd);
return();
} /**
* \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) == ) {
/* 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 -;
} if (fscanf(pf, "%d", &pidv) == && kill(pidv, ) == ) {
fclose(pf);
LogError("pid file '%s' exists. Is program already running? Aborting!",
pid_filename);
return -;
} fclose(pf);
}
return ;
}

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() #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()
#endif #endif //__UTIL_DEBUG_H__

main.c文件

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

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

<ERROR> pid file '/var/run/test_pid01.pid' exists. Is program already running? Aborting!

Linux C启动时创建pid文件的更多相关文章

  1. ARM linux内核启动时几个关键地址【转】

    转自:http://www.cnblogs.com/armlinux/archive/2011/11/06/2396787.html 1.       内核启动地址1.1.   名词解释ZTEXTAD ...

  2. Linux开机启动时执行脚本的方法

    方法 1 – 使用 rc.local利用 /etc/ 中的 rc.local 文件在启动时执行脚本与命令.我们在文件中加上一行来执行脚本,这样每次启动系统时,都会执行该脚本.不过我们首先需要为 /et ...

  3. linux 在启动时获得专用的缓冲

    如果你真的需要一个大的物理上连续的缓冲, 最好的方法是在启动时请求内存来分配它. 在启动时分配是获得连续内存页而避开 get_free_pages 施加的对缓冲大小限制的唯一 方法, 不但最大允许大小 ...

  4. 在tomcat启动时解析xml文件,获取特定标签的属性值,并将属性值设置到静态变量里

    这里以解析hibernate.cfg.xml数据库配置信息为例,运用dom4j的解析方式来解析xml文件. 1.在javaWeb工程里新建一个java类,命名为GetXmlValue.java,为xm ...

  5. Servlet --启动时创建、配置url、ServlectContext、初始化参数、获取资源

    servlet的版本的区别 2.5版本, Servlet的配置只支持在xml文件中的配置 3.0版本: Servlet的配置支持在xml文件中的配置, 也可以使用注解的方式, 默认使用注解 让服务器在 ...

  6. linux下fallocate快速创建大文件

    以前创建文件我一般用dd来创建,例如创建一个512M的文件: dd命令可以轻易实现创建指定大小的文件,如 dd if=/dev/zero of=test bs=1M count=1000 会生成一个1 ...

  7. Linux基础命令---htpasswd创建密码文件

    htpasswd htpasswd指令用来创建和更新用于基本认证的用户认证密码文件.htpasswd指令必须对密码文件有读写权限,否则会返回错误码. 此命令的适用范围:RedHat.RHEL.Ubun ...

  8. linux下使用vim创建编辑文件

    vi/vim 使用实例 如果要想用vim/vi创建一个文件(使用命令): vim test.txt   不管文件存在与否 直接输入 vi 文件名 就能够进入 vi 的一般模式 按下 i 进入输入模式( ...

  9. mysql启动失败:不能创建pid文件

    2016-03-09T07:51:38.905444Z 0 [ERROR] /usr/sbin/mysqld: Can't create/write to file '/var/run/mysqld/ ...

随机推荐

  1. 利用Bootstrap Paginator插件和KnockoutJS完成分页功能

    在最近一个项目中,需要结合一堆条件查询并对查询的结果数据完成一个简单分页功能,可是做着做着,自己的思路越来越模糊,做到心态崩溃!!! 哈哈,特此花点时间重新总结,并从最简单的分页,然后向多条件查询分页 ...

  2. [逆向工程] 二进制拆弹Binary Bombs 快乐拆弹 详解

    二进制拆弹 binary bombs 教你最快速解题,成功拆弹 最近计算机基础课,的实验lab2,二进制拆弹,可以说是拆的我很快乐了(sub n, %hair) 此处头发减n 我刚开始做的时候很是懵逼 ...

  3. Linux最小系统移植之早期打印CONFIG_DEBUG_LL

    一.几个关键宏定义 CONFIG_DEBUG_LL. CONFIG_DEBUG_LL_INCLUDE 容我慢慢道来, 首先要使能早期打印, menuconfig必须选中CONFIG_DEBUG_LL, ...

  4. Linux用户和权限管理看了你就会用啦

    前言 只有光头才能变强 回顾前面: 看完这篇Linux基本的操作就会了 没想到上一篇能在知乎获得千赞呀,Linux也快期末考试了,也有半个月没有写文章了.这篇主要将Linux下的用户和权限知识点再整理 ...

  5. C#枚举的简单使用

    枚举这个名词大家都听过,很多小伙伴也使用过, 那么枚举在开发中能做什么,使用它后能给程序代码带来什么改变,为什么用枚举. 各位看官且坐下,听我一一道来. 为什么使用枚举? 1.枚举能够使代码更加清晰, ...

  6. css3 笔记 背景

    .div1 { height: 80px; background: linear-gradient( 135deg, transparent 0, transparent 49.5%, green 4 ...

  7. 用app.net Core搞掂多国语言网站

    Asp.net Core 中文文档很少,你可以看英文的,不过英文的也是说的有点乱.这篇文章是干货. 1. 配置好你的WebApplication,使他可以支持国际化语言,修改文档Startup.cs ...

  8. 超大文本文件浏览器Snaptext,支持不限制大小的文本文件浏览

    文本文件超过1G就很少有软件可以打开了,超过10G就只有有限的几个可以打开了,那20G.30G.100G呢? Snaptext超大文本浏览器,应该是世界上最快速的文本文件浏览器,它支持基本不限制大小的 ...

  9. Spinner之下拉多选,监听ID后显示不同Frgment页面

    本人安卓小白,公司最近项目需要用到不同的类型的用户注册,周末下午写完记录一下. 网上找了一堆没有适合自己的(或者说我没找到),写的比较基础,欢迎大家多多指导. 老规矩,先上效果图 网上在线合成的GIF ...

  10. 如何学好java

    今天发现这么一篇文章,对于笔者谈的:"一方面很努力学习,一方面又觉得不踏实",我感同身受.觉得文章写得不错,在此献给一些在java中努力的朋友们,希望能有所收获. 文章原内容: 近 ...