我有一个扭曲的服务器,它为每个请求执行一些“长”任务,所以我推迟每个调用的线程。在每个请求中,我访问一个公共资源,该资源在此过程中被更改。每个请求都应该以原始数据开头,因此我在公共资源上使用deepcopy(同时调用锁获取)。它有效,但我认为它不够快。我觉得深度扫描会让事情变得缓慢。
在处理资源突变的线程化服务器时,您有什么建议?
答案 0 :(得分:3)
尝试使用工作线程中可能的最小数据进行操作。将所需的所有数据作为参数传递,并将其所有输出作为返回值(Deferred触发的值)而不是输入的突变。
然后将结果集成到reactor线程中的公共数据结构中。
这使您可以单独推断工作并避免任何其他锁定(这会导致争用,减慢速度,使其更加混乱)。
答案 1 :(得分:2)
如果您愿意,您只需将访问共享资源与threading.Lock
同步,就像在任何其他线程程序中一样,而不是复制它。
无论如何,我认为在使用和不使用深度复制的情况下对您的代码进行基准测试是值得的,并在进行优化之前进行测量以确定性能的优劣。也许它变慢的原因与深度镜检无关。
关于使用锁定的编辑:我的意思是你可以在这个资源周围使用更细粒度的锁定。我假设您的线程不仅仅是访问共享资源。您可以尝试从多个执行工作的线程中受益,然后将访问权限同步到仅涉及写入共享资源的“关键部分”。您还可以调查使您的共享资源线程安全。例如,如果有共享对象SillyExampleFriendsList
:
class SillyExampleFriendsList(object):
"""Just manipulates a couple lists"""
def __init__(self):
self._lock = threading.RLock()
self._friends = []
self._enemies = []
def unfriend(self, x):
# we lock here to ensure that we're never in a state where
# someone might think 'x' is both our friend and our enemy.
self._lock.acquire()
self._friends.remove(x)
self._enemies.append(x)
self._lock.release()
这里的要点只是通过小心使用锁可以在没有深度复制的情况下在多个线程之间共享上述对象。识别可能需要的所有情况并不是微不足道的,细粒度锁定策略可能更难以调试并且仍然会引入开销。
尽管如此,您可能根本不需要线程,锁定或深度复制,如果没有对代码进行基准测试,则不清楚是否存在需要解决的性能问题。我很好奇是什么让你认为你的代码应该或者需要更快?