【问题标题】:Share a dictionary betweeen multiple live threads在多个实时线程之间共享字典
【发布时间】:2013-07-04 20:18:32
【问题描述】:

我有一个运行多个线程的 Python (2.7) 应用程序。现在我想在我的子线程中更新一个字典,并在我的母线程中使用它的更新内容,而不使用 join()。我可以这样做吗?我不想等到我的孩子终止在我的母亲线程中使用字典的数据。

我该怎么做?

【问题讨论】:

  • 我怀疑这个问题的答案取决于您在字典中输入的内容以及访问方式。字典操作通常是线程安全的(意味着字典始终是完整的,不会由于线程切换而部分更新),但这并不一定意味着您的两个线程将在没有任何同步的情况下看到正确的数据。你能详细说明一下吗?
  • 另外,您使用的是线程还是进程?你的文字说线程,但你的标签说多处理。
  • @Blckknght 进程避免 GIL 阻塞并发线程的执行。
  • @Blckknght 我将 MAC 地址数组存储为键,并将每个 MAC 地址的 TDMN 插槽存储为字典中的值。我在一个单独的过程中从网上下载信息,以免中断我的工作过程。我必须每 600 秒(至少坐着)将成员 mac 列表与云同步一次。

标签: python python-2.7 dictionary multiprocessing


【解决方案1】:

您可以使用threading modulethread module

这是一个使用线程模块的例子:

import thread

d = dict()
m = thread.allocate_lock()

def foo():
    m.acquire_lock()
    print(d['key'])

def bar():
    d['key'] = 'value'
    m.release_lock()

if __name__ == '__main__':

    m.acquire_lock()
    t1 = thread.start_new_thread(foo,())
    t2 = thread.start_new_thread(bar,())

这说明了锁是如何同步线程访问共享资源的:只要m被锁定,foo就在等待获取它;同时,bar 更新字典并释放锁;只有这样foo 才会获得锁并继续。没有连接。

(当然,这不是你应该编写多线程代码的方式......)

编辑

如果你必须使用进程,你可以在multiprocessing module找到类似的功能。

这是一个例子:

import multiprocessing

def foo(m, d):
    m.acquire()
    print(d['key'])

def bar(m, d):
    d['key'] = 'value'
    m.release()

if __name__ == '__main__':

    manager = multiprocessing.Manager()

    m = multiprocessing.Lock()
    m.acquire()

    d = manager.dict()

    p1 = multiprocessing.Process(target=foo, args=(m, d))
    p2 = multiprocessing.Process(target=bar, args=(m, d))

    p1.start()
    p2.start()

Lock 允许进程同步,Manager 允许列表和字典等复合类型的资源共享。

【讨论】:

  • @Dan_Gittik 不,我不能使用多个线程,因为 GIL 会同时阻止多个线程的执行。如果我想要真正的并发性,我必须使用多个进程——这就是我所需要的。
  • 我更新了我的答案以解决这两种情况。请注意,要运行我的示例,您必须使用 time.sleep().join() 停止主线程/进程,以便它不会在其子进程之前终止。
  • thread 模块自 2005 年以来已被 threading 模块弃用。
  • @cerr:GIL 在 IO 上发布,即你的工作线程和下载线程可以并行运行。顺便说一句,即使 GIL 没有被释放,线程仍然会并发运行(尽管没有任何性能优势,即在这种情况下不会使用多个 CPU)。
  • 你能给我一份文档,上面写着thread 模块在 Python 2.7 中已被弃用吗?据我所知,它仅在 Python 3.x 中被标记为过时并重命名为 _thread ......无论如何,它比 threading 模块更简单明了,这是教育示例中的一个优势,所以我看到了没有理由对我的回答投反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-22
  • 2011-10-13
  • 1970-01-01
相关资源
最近更新 更多