2010-11-06 73 views
0

誰能告訴我,爲什麼下面的不作爲互斥體的一個例子的LinuxLinux互斥鎖檢查程序是否已經在運行?

#include <pthread.h> 
int main(){ 
pthread_mutex_t start; 
if (pthread_mutex_init(&start, NULL) != 0){ 
    printf("err!"); 
    return(1); 
} 
if (pthread_mutex_lock(&start) != 0){ 
    printf("err!"); 
    return(1); 
} 

pthread_mutex_unlock(&start); 
pthread_mutex_destroy(&start); 
} 
+0

爲什麼不使用pid文件&'kill(pid,0)'?它可能不是最可靠的解決方案,但實際上可用於所有應用。 – jweyrich 2010-11-07 01:03:56

回答

8

並行線程互斥是一個程序中同步線程下工作。如果你開始這個程序兩次,你會得到兩個不同的互斥體。爲了在多個進程之間進行同步,還有其他工具(在這種情況下文件鎖定可能是最簡單的)。

+1

有進程共享互斥體('pthread_mutexattr_setpshared()')。你必須把它們放在共享內存中 - 創建一個鎖文件可能要容易得多。 – nos 2010-11-07 17:06:49

0

pthread互斥鎖旨在用於單個進程中的線程;如果它位於共享內存中,它也可能工作,但是您在上面分配它的方式,兩者都不會。

因此,調用兩個程序副本,創建兩個互斥體,每個都需要自己,每個人都很高興 - 除非這不是您想要的。

我認爲只允許一個副本的最簡單方法是打開一個文件進行寫入並對其進行獨佔文件鎖定(請參閱flock())。

另一種可能性是嘗試綁定抽象名稱空間中的unix套接字;請參閱man unix(7),但是這是Linux專用的。

0

我發現一個進程檢查並查看另一個進程是否還在運行的最佳方式是使用鎖定文件,正如在註釋中添加了信號一樣。

如果程序B不應該開始,如果程序A尚未啓動,活着並響應,或者程序A不負責啓動程序B,但應該做一些不同的事情,如果程序B沒有啓動一段時間。這實際上是一種非常常見的情況。

試試這個:

  • 計劃A開始,寫入其PID到/var/run/a.pid
  • B計劃開始,寫入其PID到/var/run/b.pid
  • 程序B讀取/var/run/a.pid並把它發送一個SIGUSR1
  • 程序A對SIGUSR1信號處理程序讀取/var/run/b.pid並把它發送一個SIGUSR1爲ACK
  • 方案B知道程序A正在運行並可以繼續運行
  • 程序A知道程序B已經啓動,並可以改變其行爲

這是非常簡化和基本的IPC,但工程。一個更優雅的方法是通過mmap()在進程之間共享內存段,但即使如此,您也不應該相信鎖是另一個進程實際響應的標誌,特別是在第二個進程中沒有處理飢餓問題。相反的情況也是如此。

這也是一個非常以POSIX爲中心的答案,如果它不適用,請詳細描述你的平臺。

相關問題