Jython和Jython将支持多线程。方法sendMessage
用于接收来自特定客户机的消息,客户机可以向其他几个客户机发送相同的消息(这是参数receivers
的作用,而{receiveMessage
用于接收从其他客户端发送的特定客户端的消息。在
问题是我是否需要方法sendMessage
和receiveMessage
的锁?我认为没有必要,因为即使一个客户机X正在接收它的消息,另一个客户机Y附加到消息池以将消息传递给客户机X是完美的。我认为对于defaultdict/list,append/pop都是原子的,不需要保护。在
如果我错了,请随时纠正我。在
from collections import defaultdict
class Foo:
def __init__(self):
# key: receiver client ID, value: message
self.messagePool = defaultdict(list)
def sendMessage(self, receivers, message):
# check valid for receivers
for r in receivers:
self.messagePool[r].append(message)
def receiveMessage(self, clientID):
result = []
while len(self.messagePool[clientID]) > 0:
result.append(self.messagePool[clientID].pop(0))
return result
我认为这个问题对于CPython here和here来说已经得到了很好的回答(基本上,因为GIL,您是安全的,尽管文档中没有正式提到这一点(比如on defaultdict或list)。但我理解您对Jython的担心,所以让我们使用一些官方来源来解决它,比如Jython source code。一个Python} ,上面有这样的代码:
list
就是一个javaish ^{由于我们有这些方法synchronized,所以我们可以确保列表附录和pop在Jython中也是线程安全的。因此,您的代码似乎是安全的wrt线程。在
尽管
Queue
建议仍然有效,但它确实更适合这个用例。在我建议使用
Queue
而不是list
。它是为带锁的append\pop-in线程设计的。在竞争条件是指两个或多个线程同时更改某些全局状态。在
在
sendMessage
的代码中,您正在更改self.messagePool[r]
,它是一个全局对象。因此,self.messagePool[r]
应该在附加新项之前锁定。在与您的
receiveMessage
函数相同。在list.append
和list.pop
是O(1)和O(1)运算的铠装,因此很少会引起任何竞争条件。然而,风险仍然存在。在相关问题 更多 >
编程相关推荐