zoukankan      html  css  js  c++  java
  • linux下C程序:运行单个实例

    原文地址:http://blog.chinaunix.net/uid-24622573-id-276141.html

     对于很多服务来说,在同一个服务器上只能运行一个实例,那么通过什么方法来保证程序同一时刻只有一个实例运行呢?通过编写shell脚本来管理程序的启动、停止是个不错的方法。在启动时,shell脚本会创建进程标识文件(存储正在运行实例的pid)以表明已经有实例在运行,如果文件已存在,则说明已有实例在运行,不需要做任何事;在退出时,shell脚本会删除进程标识文件,表明没有实例运行。

    shell脚本管理方法在应用程序之上再包了一层,那么能不能直接在程序开始运行时自己判断是否有实例在运行呢,答案是肯定的。原理其实差不多,还是要借助公用资源---文件,当然不仅仅是文件而已,还需要文件锁的支持。大致思路是这样的:程序在开始运行时对特定文件进行加锁(不存在则创建),如果加锁成功,则实例开始运行;如锁已经被占有,则说明已经有实例在运行,则程序直接退出;另外在实例运行完毕后对文件的锁也随着丢掉了。这样就能保证每次只有一个程序实例在运行。

    具体步骤如下:

    1. 打开特定文件(如/var/run/mydaemon.pid),如不存在则创建之;

    2. 使用fcntl对文件整个区域加劝告锁。

    3. 如果加锁成功,则继续执行后续代码,并将pid写入文件;如加锁不成功,说明已经有实例在运行,直接退出。

    实现示例:

    #include <stdio.h>

    #include <stdlib.h>

    #include <unistd.h>

    #include <fcntl.h>

    #include <printf.h>

    #include <string.h>

    #include <errno.h>

    #include <sys/stat.h>

    #define LOCKFILE "/var/run/mydaemon.pid"

    #define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

    /* set advisory lock on file */

    int lockfile(int fd)

    {

            struct flock fl;

            fl.l_type = F_WRLCK;  /* write lock */

            fl.l_start = 0;

            fl.l_whence = SEEK_SET;

            fl.l_len = 0;  //lock the whole file

            return(fcntl(fd, F_SETLK, &fl));

    }

    int already_running(const char *filename)

    {

            int fd;

            char buf[16];

            fd = open(filename, O_RDWR | O_CREAT, LOCKMODE);

            if (fd < 0) {

                    printf("can't open %s: %m\n", filename);

                    exit(1);

            }

            /* 先获取文件锁 */

            if (lockfile(fd) == -1) {

                    if (errno == EACCES || errno == EAGAIN) {

                            printf("file: %s already locked", filename);

                            close(fd);

                            return 1;

                    }

                    printf("can't lock %s: %m\n", filename);

                    exit(1);

            }

            /* 写入运行实例的pid */

            ftruncate(fd, 0);

            sprintf(buf, "%ld", (long)getpid());

            write(fd, buf, strlen(buf) + 1);

            return 0;

    }

    int main(int argc, char *argv[])

    {

            if (already_running(LOCKFILE))

                    return 0;

            /* 在这里添加工作代码 */

            printf("start main...\n");

            sleep(100);

            printf("main done!\n");

            exit(0);

    }

  • 相关阅读:
    VUE.JS 使用axios数据请求时数据绑定时 报错 TypeError: Cannot set property 'xxxx' of undefined 的解决办法
    vue-cli:渲染过程理解2(vue init webpack方式创建)
    vue2 mint-ui loadmore(下拉刷新)
    vue-resource: jsonp请求百度搜索的接口
    vue中组件绑定事件时是否加.native
    vue 子组件修改父组件传来的props值,报错
    测试开发工程师的角色
    不要信仰BAT!
    简历不能怎么写?
    测试工程师面试,全国各地有哪些知名互联网公司可以去?
  • 原文地址:https://www.cnblogs.com/bigben0123/p/2949410.html
Copyright © 2011-2022 走看看