在一些情況下,一個進程只能產生一個實例來執行。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));
- }