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);
}