在一些情況下,一個進程只能產生一個執行個體來執行。Unix環境,提供了檔案-記錄鎖(file- and record-locking)機制,提供了事項單一實例進程的基本解決方案。
假如,一個進程在開始運行時,產生了一個檔案,並且,對整個檔案上鎖,並且,只有一個這樣的寫鎖允許產生。
如果,後續的進程要試圖產生寫鎖,會導致失敗。這暗示了,前面已經有執行個體運行了。
下面一個判斷是否有執行個體啟動並執行方法。每個執行個體,都會試圖產生一個檔案(/var/run/daemon.pid).如果檔案已經鎖上了,lockfile方法,返回失敗,判斷函數返回1,表示進程已經運行了。如果沒有執行個體運行,程式,清空檔案,寫入進程id,返回0.
下面為一個實現的程式:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <syslog.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#define LOCKFILE "/var/run/daemon.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
int already_running(void);
int lockfile(int );
int main(int argc,char * argv[])
{
int val = already_running();
if(val == 0)
{
printf("sart to running...\n");
}
else
{
printf("alredy running...\n");
exit(0);
}
while(1)
{
sleep(3);
printf("...\n");
}
return 0;
}
int already_running(void)
{
int fd;
char buf[16];
fd = open(LOCKFILE,O_RDWR|O_CREAT, LOCKMODE);
if(fd < 0)
{
syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno));
exit(1);
}
if(lockfile(fd) < 0)
{
if (errno == EACCES || errno == EAGAIN)
{
close(fd);
return 1;
}
syslog(LOG_ERR,"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;
}
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));
}