2011-02-15 132 views
3

我有一個守護程序,它接受套接字連接並根據連接的性質讀取或寫入一組動態文件。因爲我的守護進程是多線程的,所以可能存在相同的文件可能被多個線程寫入。由於我的文件列表是動態的,並且不是固定的,我不確定如何讓一個線程不會碰到另一個線程。出於性能方面的考慮,我希望線程能夠同時寫入不同的文件,而不是同時寫入不同的文件。線程安全多文件寫入

其他問題建議使用互斥鎖,但我不完全清楚在這種情況下互斥鎖將如何幫助 - 文件列表是動態的,只有線程已知。

在這種情況下使用文件鎖定是否合適?如果是這樣,那麼如何以線程安全的方式實現文件鎖定?

+0

無論如何,你需要對每個文件進行互斥訪問 - 你可以用Matthew PK的「文件代理」概念來做到這一點,或者甚至只是一個從(絕對)文件名到互斥量的散列表(顯然是修改散列表本身也應該使用互斥量序列化)。 – 2011-02-15 00:34:35

+1

@Conrad Meyer:散列`st_dev` /`st_ino`組合可能比文件名更好,因爲與實際上唯一標識文件的文件名不同。 – caf 2011-02-15 05:27:33

回答

2

flock會工作正常。它不鎖定文件描述符,它鎖定實際的文件。

已被排除在外的文件不能被另一個進程或線程獨佔鎖定。這將打破鎖的整個目的。

請注意,這些鎖是諮詢。一個不使用flock的進程可以愉快地覆蓋該文件,即使另一個進程擁有獨佔權。

1

我會使用事件代理模式。每個插入線程觸發一個事件(具有文件的參數),然後事件由中央文件代理處理,並帶有當前正在寫入的共享文件集合。

如果無法寫入文件,請決定要做什麼......否則報告成功。

多個偵聽器,一箇中央文件鎖集合,多個作者。

1

我不能說這將是「最佳」的解決方案,但我建議是這樣的:

維護一個包含兩個東西一個結構的鏈接列表:

  1. 的filename
  2. 與文件關聯的條件等待變量。

流A.當守護進程接收到請求時,互斥鎖鎖定列表並檢查文件名是否在列表中。如果不是,則使用新條件等待變量爲鏈接列表添加一個新條目,供其他線程使用。釋放互斥鎖。執行文件操作。完成後,鎖定鏈接列表併除去該文件的結構條目,然後通過等待對象發信號通知其他線程。

流B.如果請求來自同一個文件,它將鎖定列表並查找包含在列表中的文件名。如果它在列表中,請抓住等待變量並等待它。當線程被髮信號時,在列表上抓住一個鎖並查看文件是否在列表中(可能是另一個線程在你之前拿到了文件名上的鎖)。如果不是,請按照流程A進行操作。如果是,請抓取新結構中的等待變量並再次等待,直到發出信號,然後再次執行上述步驟。