很多时候,同一个服务器可以运行多个相同的进程,导致结果和预期的不一致。参考了很多资料,最后决定使用文件锁来保持进程的唯一性。如果使用fcntl文件锁操作,第2个进程也可以启动,只是无法执行到代码的核心模块,从而保证核心代码执行的唯一性。简单代码为:
int CreateFileLock(const char* pidFile)
{
int fd;
int ret = 0;
fd = open(pidFile, O_WRONLY);
if(fd == -1) {
printf("Unable to open the file\n");
return -1;
}
static struct flock lock;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
lock.l_pid = getpid();
ret = fcntl(fd, F_SETLKW, &lock);
return ret;
}
如果要保证进程只启动一个,如果多启动一个的话,自动退出,以上就没办法做到。以下为实现方式:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
/*判断进程是否存在,如不存在则启动*/
int IsProcessExist(char *as_Process)
{
char lz_ExistProcess[200];
char lz_TmpStr[200];
FILE *lpf_Process;
memset(lz_ExistProcess, 0x00, sizeof(lz_ExistProcess));
memset(lz_TmpStr, 0x00, sizeof(lz_TmpStr));
sprintf(lz_ExistProcess, "ps -e |grep -c %s >Process.txt",as_Process);
system(lz_ExistProcess);
lpf_Process = fopen("Process.txt", "r");
if (lpf_Process == NULL)
{
printf("Open File Process.txt Error...\n");
fflush(NULL);
fclose(lpf_Process);
return (0);
}
fgets(lz_TmpStr, 200, lpf_Process);
printf("lz_TmpStr=%s\n",lz_TmpStr);
if ( atoi(lz_TmpStr) <=1 ) /*空文件,进程未启动*/
{
printf("66666666666\n");
return 0;
}
fflush( NULL );
fclose(lpf_Process);
system("rm Process.txt");
return(-1);
}
int WriteFileLock(const char* pidFile)
{
int fd;
int ret = -1;
int fd2;
pid_t pid2;
pid_t pid;
char tmp_Str[100]={0};
ret = IsProcessExist("ConMain");
if (ret == 0)
{
sprintf(tmp_Str, "rm -f %s",pidFile);
system(tmp_Str);
}
fd = open(pidFile, O_RDWR|O_CREAT|O_EXCL, 0644);
if(fd < 0)
{
if(errno== EEXIST)
{
if((fd2 = open(pidFile, O_RDONLY | O_CREAT)) == -1)
{
printf("read %s fail\n",pidFile);
return 0;
}
pid = getpid();
if( read(fd2, &pid2,sizeof(pid2)) != sizeof(pid))
{
close(fd2);
close(fd);
printf("more than one process is running.\n");
return -1;
}
}
}
pid = getpid();
if(write( fd,&pid,sizeof(pid)) != sizeof(pid))
{
printf("only one process will get the lock.\n");
close(fd);
return -1;
}
close(fd);
return 0;
}
int main()
{
int ret = 0;
pid_t pid2;
int flag;
int fd;
pid_t pid;
ret = WriteFileLock("ConMain.lock");
if (ret < 0)
{
printf("already one process run.\n");
exit(0);
}
while(1)
{
}
}