http://www.zeromq.org/blog:multithreading-magic
基于消息的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实现这样一个系统,这样我就不需要了 锁定以控制ClientA和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如何在不使用锁定消息的情况下解决此类问题?
谢谢
答案 0 :(得分:1)
一个简单的答案是您可以使用并发队列模拟锁。
假设您有一个大小为1的队列已填满。客户端将尝试从队列中获取值。成功的那个将执行操作并将值放回队列中。失败者将进入睡眠状态,并在成功完成客户端后继续。
这可以说是一个学术范例。实际上,您可能正在使用数据库系统中的事务而不是客户端之间的锁定。
答案 1 :(得分:1)
ZeroMQ为您提供了一个工具箱,可以帮助您解决这个问题,但最佳解决方案在很大程度上取决于细节。
例如,如果客户端使用更新锤击服务器,但客户端的唯一目的是增加A,它可以简单地发送包含增量到服务器的值的消息,而不知道A的确切值。
更一般地说,服务器可以向客户端发布更新,客户端可以请求服务器更新A的值,如clustered hashmap protocol中所示。但是,就我所见,该协议不会检测同一密钥的并发更新。您可以修改它以添加乐观锁定或尝试在协议之上构建一些东西。 sample implementation让服务器在单个线程中执行更新并对更新进行编号,因此您可以使用该序列号。但它仍需要一些努力。
有关协议的更多详细信息,请参阅the ZeroMQ guide