2012-07-24 62 views
2

這就是問題所在: 我不喜歡我的程序的多個實例,這就是我禁用它們的原因。我的程序打開一個特定的MIME類型。在我的系統(Ubuntu的12.04),當我雙擊其中的一個文件,就執行:如何同時處理多個併發實例?

/usr/bin/myprogram /path/to/double/clicked/file.myextension 

正如我所說的,我不喜歡多個實例,因此,如果該程序已經運行和用戶選擇打開其中一個文件,DBus消息正在發送到已經存在的實例,以便照顧打開的文件。所以,如果有一個已經運行的實例,用戶可從中選擇3個文件和我的程序打開並擊中[確定]按鈕,系統執行:

/usr/bin/myprogram /path/to/double/clicked/file1.myextension 
/usr/bin/myprogram /path/to/double/clicked/file2.myextension 
/usr/bin/myprogram /path/to/double/clicked/file3.myextension 

所有這些實例的檢測已經運行的實例,併發送打開文件。根本沒有問題,直到現在。

但是,如果沒有已經運行的實例並且用戶選擇用我的程序完全打開3個文件會怎麼樣?再次,系統將同時調用,:

/usr/bin/myprogram /path/to/double/clicked/file1.myextension 
/usr/bin/myprogram /path/to/double/clicked/file2.myextension 
/usr/bin/myprogram /path/to/double/clicked/file3.myextension 

和所有這些情況都將認識到,有一個已經運行的情況下,它會試圖發送一個消息的DBus到已運行的情況下,它會退出。所以,所有這3個進程都會做同樣的事情,沒有任何東西會運行。

我該如何避免這個問題?

PS:

bool already_runs(){ 
return !system("pidof myprogram | grep \" \" > /dev/null"); 
} 
+0

打開多個文件時,是否應該將所有三條路徑都傳遞給一個命令?例如。/usr/bin/myprogram file1 file2 file3 – Alan 2012-07-24 14:16:58

+0

@Alan:無論是否存在,至少仍然有人可能通過其他方式快速連續運行該程序三次:-)需要的是方式之一的程序副本宣佈自己是「第一個」。例如,這可能是通過獲取特定文件的鎖,但我不知道QT,如果QT提供了一些幫助機制,這將是一個垃圾回答。 – 2012-07-24 14:26:11

+0

您不僅需要檢測另一個實例正在運行,而且還有一個正在運行的實例已經接受它是一個實例。 – bames53 2012-07-24 14:42:14

回答

0

我會使用一些共享內存來存儲第一進程的PID:爲了我執行下面的代碼來檢測是否有已在運行的實例。 QSharedMemory班將幫助你在這裏。

您的程序應該做的第一件事就是嘗試創建一個共享內存段(使用您自己編寫的密鑰)並將其存儲在其中。如果創建調用失敗,則可以嘗試附加到段。如果成功,那麼你可以從它讀取原始進程的PID。

編輯:另外,remomber在寫入或讀取共享內存之前使用lock(),然後在完成時調用unlock()。

+0

鏈接不'這裏是[QSharedMemory的Qt 4.8參考](http://doc.qt.io/qt-4.8/qsharedmemory.html)和[QtredMemory的Qt 5.5參考](http://doc.qt。 IO/QT-5/qsharedmemory.html)。 – basic6 2015-10-24 21:53:15

0

在DBus中執行此操作的標準方法是在總線上獲取應用程序的名稱;一個實例將贏得比賽並且可以成爲正在運行的實例。然而,你應該能夠使用Qt功能來完成這項工作,它將與你的其他應用程序更好地集成在一起;見Qt: Best practice for a single instance app protection

相關問題