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

阅读更多

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

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

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

#define _SINGLE_INSTANCE_H__

#include

#include

#include

#include

#include

#include

#include

#include

//定义锁文件。 把进程的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);

}
 

你可能感兴趣的:(Linux,F#,Blog)