2013-05-02 57 views
2

http://www.zeromq.org/blog:multithreading-magic沒有鎖在ZeroMQ

實現多線程應用中的基於消息的ZeroMQ框架實現並行/多線程應用程序,而無需使用鎖。

問題>它如何在下面的例子中起作用?

例如:

我們各有兩個客戶端在同一個數據庫中讀取數據,再後來放回去修改結果。

ClientA: Read data A, modified A.value = A.value + 1 then write data A back to database 
ClientB: Read data A, modified A.value = A.value + 2 then write data A back to database 

問題>我無法弄清楚如何實施與ZeroMQ這樣的系統,這樣我不需要 鎖來控制客戶端A和ClientB的行爲。它如何防止以下 案件發生。

ClientA read data A first 
ClientB read data A second 
ClientB write data A back // now data.value has been increased by two 
ClientA write data A back // now the conflict! because the original value of A has been 
          // modified by ClientB and ClientA has no information about it. 
          // If ClientA writes the A back without knowing the update A 
          // then the changes made by ClientB will be voided. 

ZeroMq如何解決這個問題,而不使用它的消息使用鎖定?

謝謝

回答

1

一個簡單的答案是,你可以模擬一個併發隊列的鎖。

假設你有一個填滿的大小爲1的隊列。客戶將嘗試從隊列中獲取值。成功的將執行操作並將值放回隊列中。失敗的人會去睡覺,並在成功的客戶完成後繼續。

這可以說是一個學術範例。事實上,您可能會在您的數據庫系統中使用事務,而不是客戶端之間的鎖。

+0

我認爲ZeroMQ會採取不同的方式。 – q0987 2013-05-02 23:52:25

+1

ZeroMQ正在解決「在獨立進程之間傳遞數據」的不同問題,您的示例是「調解對共享資源的訪問」之一。您可以使用另一種方法實現一個(您可以通過使用鎖來將數據寫入共享資源,或者通過在進程之間使用消息傳遞訪問令牌來在進程之間傳遞數據)。這可能是爲什麼我實施一個鎖而不是做更多的消息-y似乎很奇怪。 – yiding 2013-05-03 00:09:20

+0

我期望看到一個解決方案,它顯示了當併發線程訪問共享數據時,zeromq如何解決經典問題。 – q0987 2013-05-04 03:01:29

1

ZeroMQ爲您提供了一個工具箱,使您能夠解決這個問題,但最好的解決方案非常依賴於細節。例如,如果客戶端使用更新錘擊服務器,但客戶端的唯一目的是增加A,則它可以簡單地發送包含增值的消息到服務器的消息,而不知道A的確切值

更一般地說,服務器可以向客戶端發佈更新,並且客戶端可以請求服務器更新A的值,如clustered hashmap protocol。但是,據我所知,這個協議沒有檢測到同一個密鑰的併發更新。您可以對其進行修改以添加樂觀鎖定,或嘗試在協議之上構建一些東西。 sample implementation使服務器在單個線程中執行更新併爲更新編號,以便您可以使用該序號。但它仍然需要一些努力。

有關協議的更多細節,請參見the ZeroMQ guide