2011-05-31 55 views
7

我尝试使用临时文件:文件锁定为Linux

char *temp = tempnam(NULL, "myapp_"); 
printf("Tempname: %s", temp)  // Prints /tmp/myapp_random 
while (1) { } 

但是当我检查/tmp(而应用程序仍在运行),该myapp_random是不存在的!

至于使用文件锁,我不能很好地把握它,我试着看着<fcntl.h>,但它似乎专注于锁定文件的指定部分。我只是想完全使用该文件作为锁(这就是为什么我更喜欢尝试临时文件方法)。

任何想法?

+0

这看起来像http://stackoverflow.com/questions/800730/cc-how-to-tell-if-a-program-is-already的副本-running – 2011-05-31 04:24:49

+0

@Richard,这个问题是专门针对Windows的。 (1)'tempnam'在VC2005中被弃用,(2)代码引用'/ tmp/myapp_random',这实际上并不是Windows的东西。 – paxdiablo 2011-05-31 05:48:46

回答

9

tempnam不是创建该文件,它只是给你一个文件名,在你调用它时不存在。

您仍然必须自行创建档案,因此仍然存在另一个进程可能潜入并在您之前创建的竞争条件。

你实际上并不需要想要使用tempnam,因为这会为每个进程提供自己的文件名,并且它们可以同时运行。你需要的是一个固定的文件名(例如/tmp/myapp.lck),每个进程打开然后尝试到flock

对于锁定文件,您最好用flockfcntl会给你一个更细的锁定(文件的一部分),但这不是真正的要求。

的代码将运行是这样的:

if ((mylockfd = open ("/tmp/myapp.lck", O_CREAT | O_RDWR, 0666)) < 0) { 
    // error, couldn't open it. 
    return; 
} 
if (flock (mylockfd, LOCK_EX | LOCK_NB) < 0) { 
    // error, couldn't exclusive-lock it. 
    return; 
} 
: 
// Weave your magic here. 
: 
flock (mylockfd, LOCK_UN); 

这可能需要一些工作,但应该是一个良好的开端。更广义的解决办法是这样的:

int acquireLock (char *fileSpec) { 
    int lockFd; 

    if ((lockFd = open (fileSpec, O_CREAT | O_RDWR, 0666)) < 0) 
     return -1; 

    if (flock (mylockfd, LOCK_EX | LOCK_NB) < 0) { 
     close (lockFd); 
     return -1; 
    } 

    return lockFd; 
} 

void releaseLock (int lockFd) { 
    flock (lockFd, LOCK_UN); 
    close (lockFd); 
} 

// Calling code here. 

int fd; 
if ((fd = acquireLock ("/tmp/myapp.lck")) < 0) { 
    fprintf (stderr, "Cannot get lock file.\n"); 
    return 1; 
} 

// Weave your magic here. 

releaseLock (fd); 
+0

我不关心这种竞争状况......应用程序的创建是由人类完成的。此外,大多数情况下,应用程序不能正常关闭(即它崩溃或ctrl + c)...所以如果我打开文件的“r”,似乎并没有在磁盘上创建它,但如果我用“w”打开它,它创建它,但是当我的程序崩溃时,文件仍然存在。任何解决方案?谢谢 – user657178 2011-05-31 04:07:38

+0

万分感谢! YAY:D 0_CREAT | 0_RDWR,0666工作...我想在你只有0_CREAT之前,但这正是我所需要的。非常感谢 :) – user657178 2011-05-31 04:30:20