如何在多线程系统中使用python字典

2024-05-13 01:47:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我设计了一个系统,通过套接字获取数据,并将其存储到字典中作为数据库。然后,我的所有其他模块(GUI、analysis、write_-u-to-u-log_-file等)都将访问数据库,并对字典执行所需的操作,例如制作小部件/将字典复制到日志文件。但是由于所有这些事情都以不同的速率发生,所以我选择让每个模块都在自己的线程上,这样我就可以控制频率。在

在主运行函数中有如下内容:

    from threading import Thread
    import data_collector
    import write_to_log_file

    def main():
        db = {}
        receive_data_thread = Thread(target=data_collector.main, arg=(db,))
        recieve_data_thread.start()  # writes to dictionary  @ 50 Hz
        log_data_thread = Thread(target=write_to_log_file.main, arg(db,))
        log_data_thread.start()  # reads dictionary  @ 1 Hz

但是这两个模块似乎并不是在同一个dictionary实例上工作,因为log_data_线程只会打印出空字典,即使data_collector显示它插入到字典中的数据也是如此。在

字典中只有一个编写器,所以我不必担心线程会相互踩在一起,我只需要找出一种方法,让所有模块在编写当前数据库时读取它。在


Tags: 模块toimportlog数据库dbdata字典
3条回答

这应该不是问题。我还假设您正在使用线程模块。我需要了解更多关于数据采集器和写入日志文件的操作,以找出它们不工作的原因。在

从技术上讲,你甚至可以有一个以上的线程写入,这不会是一个问题,因为GIL将负责所有需要的锁定。当然,你不会从中得到超过一个CPU的工作。在

下面是一个简单的例子:

import threading, time

def addItem(d):
  c = 0
  while True:
    d[c]="test-%d"%(c)
    c+=1
    time.sleep(1)

def checkItems(d):
  clen = len(d)
  while True:
    if clen < len(d):
      print "dict changed", d
      clen = len(d)
    time.sleep(.5)

DICT = {}
t1 = threading.Thread(target=addItem, args=(DICT,))
t1.daemon = True
t2 = threading.Thread(target=checkItems, args=(DICT,))
t2.daemon = True
t1.start()
t2.start()

while True:
  time.sleep(1000)

Use a Queue.Queue将值从读线程传递到单个写入线程。将队列实例传递给每个data_collector.main函数。它们都可以调用队列的put方法。在

同时,write_to_log_file.main也应该传递给同一个队列实例,它可以调用队列的get方法。 当项目从队列中拉出时,可以将它们添加到dict。在

另见:Alex Martelli,关于为什么Queue.Queue is the secret sauce of CPython multithreading。在

与其使用内置的dict,不如考虑使用multiprocessing库中的Manager对象:

from multiprocessing import Manager
from threading import Thread
from time import sleep

manager = Manager()
d = manager.dict()

def do_this(d):
    d["this"] = "done"

def do_that(d):
    d["that"] ="done"

thread0 = Thread(target=do_this,args=(d,))
thread1 = Thread(target=do_that,args=(d,))
thread0.start()
thread1.start()
thread0.join()
thread1.join()

print d

这为您提供了一个标准的库线程安全的同步字典,它应该很容易在不改变设计的情况下切换到当前的实现中。在

相关问题 更多 >