让程序单例运行的另一种方法[i8320]

eric在blog上发过一种方法。也已经封装得很好了。
因为我没有去了解dbus的用法,所以看不懂。

我是通过文件锁的方法实现程序单例执行。这也是Linux下的实现单例守护进程的常用办法。

下面是singleinstance头文件内容。#ifndef _SINGLE_INSTANCE_H__

#define _SINGLE_INSTANCE_H__

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <string.h>

#include <errno.h>

#include <sys/stat.h>

//定义锁文件。 把进程的pid写入锁文件,放在/var/run目录下这是通用的方法。

#define LOCKFILE "/var/run/com.heimutuzhu.heyc.pid"

 

 

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

 

//文件锁。

int lockfile(int fd)

{

    struct flock fl;

    fl.l_type = F_WRLCK;

    fl.l_start = 0;

    fl.l_whence = SEEK_SET;

    fl.l_len = 0;

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

}

//检查是否运行。

int already_running(void)

{

    int fd;

    char buf[16];

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

    if(fd < 0)

    {

        fprintf(stderr,"can't open %s: %s", LOCKFILE, strerror(errno));

        exit(1);

    }

    if(lockfile(fd) < 0)

    {

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

        {

            close(fd);

            return 1;

        }

        fprintf(stderr,"can't lock %s: %s", LOCKFILE, strerror(errno));

        exit(1);

    }

    ftruncate(fd, 0);

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

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

    return 0;

}

 

#endif
下面是使用。
通过发布  一个消息。"User.Test.Signal",通知已经起来的实例显示窗口。(参见我的 注册按键那篇)
使用这些,你只需要实现user_main即可。//这个定义自己的一个消息。

#define PUB_MSG  "com.heimutuzhu.heyc.deiconify"

static int ED_HANDLE;

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

{

    pid_t child;

    if( (child=fork()) < 0 )

    {

        g_print("error : fork() < 0 \n");

        return 1;

    }

    else if( child == 0)

    {

        if(EvtSysLibraryOpen(&ED_HANDLE)!=0)

        {

            fprintf(stderr, "Error EvtSysLibraryOpen():\n");

            return -1;

        }

        if(already_running())

        {

            EvtSysEventPublish(ED_HANDLE, "User.Test.Signal",PUB_MSG);

            EvtSysLibraryClose(ED_HANDLE);

            fprintf(stderr,"============  already_running EXIT =============\n");

            return 0;

        }

        if((EvtSysEventSubscribe(ED_HANDLE, "User.Test.Signal", NULL, __OnNotifyDeiconify,window, &ed_id))!=0)

       {

           fprintf(stderr, "Error EvtSysLibraryOpen()");

       }

       else

       {

           ED_OK = TRUE;

       }

        user_main(argc, argv);

        EvtSysLibraryClose(ED_HANDLE);

        exit(0);

    }

    printf("child pid = %d\n", child);

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值