2014-03-02 69 views
1

假設您有一個寫入文件的進程,並且需要1秒鐘(理論)才能執行。您在文件上加鎖以防止在寫入時寫入;但是這個問題應該適用於任何競爭條件。最好是「循環和檢查」或「等待信號」(例如PHP中的pcntl_sigwaitinfo和pcntl_signal)。睡眠的最佳實踐

如果首選「循環和檢查」,爲獲得最佳性能,等待接收鎖的進程進入休眠狀態的時間應該等待多久,換句話說,應該多久檢查一次進程的鎖狀態?

假設CPU週期時間爲20納秒(ns):

如果等待1個整體秒,最大浪費的時間是(1S - 納秒)或幾乎完整的第二假設後的前一過程完成爲1ns最後檢查。但是,經常檢查也是浪費。我正在考慮使用

[ (Execution Time/(4 * Execution Time) ]. 

這個公式應該減少到給定執行長度的4倍。你們有什麼感想?

+0

想要避免等待和信號,如果信號量是必需的,因爲它們不是PHP中的跨平臺。 – SilverFox

+0

對於文件系統,我不是專家,但對於PHP來說,這似乎太低級了。 –

+0

平均執行時間從測試中收集,而不是通過實時計算。 – SilverFox

回答

0

我無法真正理解你所要做的事情,所以我會做出一些假設。

我假設你正在鎖定文件以保持內容的完整性,而不是創建某種基於文件的條件,因爲你不需要文件來滿足條件。

我會假設你已經忽略了一個事實,即環和檢查是引入競爭條件做任何事的好辦法,考慮下面的代碼

if (can_lock_file()) 
    lock_file(); 

如果不止一個上下文執行,和我如果兩個上下文同時調用can_lock_file,它們都可以獲得正返回值,並且都嘗試鎖定文件,根據代碼,阻塞和/或死鎖其中一個上下文。

最好的建議是不要在代碼中做出這樣的決定,沒有好的方法讓它正確。

這是一些代碼,它有8個線程將隨機生成的數據寫入單個輸出文件,該文件的完整性通過互斥鎖以適當的方式保存,數據和進程的性質將決定真正的互斥量我採取了最好的猜測:

<?php 

class FileWriter extends Thread { 
    public function __construct($file, $lock) { 
     $this->file = $file; 
    } 

    public function run() { 
     /* the file does not need to be locked while data is generated */ 
     $data = []; 
     while (count($data) < 1000) { 
      $data[] = md5(mt_rand()*microtime()); 
     } 

     $tid = $this->getThreadId(); 

     foreach ($data as $line) { 
      /* the lock need only be held while the file is written */ 
      Mutex::lock($this->lock); 
      fprintf(
       $this->file, 
       "%s#%lu: %s\n", __CLASS__, $tid, $line); 
      Mutex::unlock($this->lock); 
     } 
    } 

    protected $file; 
    protected $lock; 
} 


$threads = []; 
$thread = 0; 

$handle = fopen("test.txt", "w+"); 
$lock = Mutex::create(); 

while ($thread<8) { 
    $threads[$thread] = new FileWriter($handle, $lock); 
    $threads[$thread]->start(); 
    $thread++; 
} 

foreach ($threads as $thread) 
    $thread->join(); 


Mutex::destroy($lock); 
?>