【问题标题】:Multiprocessing threadpool concatenates arguments多处理线程池连接参数
【发布时间】:2018-12-04 22:07:53
【问题描述】:

我有一个很长的列表data,假设它看起来像这样:

[(a, a, 1),
(b, b, 1),
(c, c, 1),
(d, d, 1),
(e, e, 1),
(f, f, 1),
(g, g, 1),
(h, h, 1),
(i, i, 1),]

我正在尝试如下使用多线程:

from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(4)
pool.starmap(help_func, data)

Help_func如下:

def help_func(in_vala, in_valb, in_valc):
    print("asking for " + str(in_vala) + " asking for " + str(in_valb))
    receiver(in_vala)

接收器是一个简单的测试函数:

def receiver(group):
    print(group)

当我运行我的程序时,我可以看到 help_func 的输出是正确的,即它枚举了 data 的值。

但是,当我查看在接收器()处生成的值时,我注意到一些奇怪的打印,如下所示:

a
b
c
de
e
f
gh
i

我很难理解为什么会出现这种情况。调用receiver的时候出了点问题,可能是receiver带来的non-blocking可能吧?

我应该如何解决这个问题。

另外,当我使用 ThreadPool(1) 时,我没有看到这个问题。我的实际问题有一个更大的函数,它是从 help_func 调用的,所以我想理想地在多个线程下运行它。

【问题讨论】:

    标签: python-3.x multiprocessing threadpool


    【解决方案1】:

    您遇到了经典的并发问题:您认为是原子的一切都不是。实际上 print 函数会打印两件事:传递给它的数据和 end 参数,默认情况下是 "\n"

    所以连接是一个线程写入数据,然后另一个写入数据,然后都写入新行的结果。

    this Raymond Hettinger talk 解释得更好。

    P.S.:我希望你知道 python GIL。简而言之:只有一条 python 指令可以同时在所有 python 线程中执行。如果您想加快函数的执行速度 - 使用多处理,当您的线程大部分时间处于阻塞状态时,多线程很有用(例如,网络主要等待数据包到达,因此线程可以)

    【讨论】:

    • 是的。谢谢。发布后我想出了一个潜在的解决方案。基本上,我可以在调用receiver() 之前使用lock.acquire(),之后使用lock.relase()。但是,我不确定的一件事是:如果从 receiver() 调用的函数将执行并且只有当所有调用都完成时才会释放锁?那正确吗?这是否可能使在获取和释放之间进行的所有调用中线程无效?
    • 是的,这就是锁的处理:在你的程序中放足够多的锁,你就发明了最复杂的单线程应用程序。多线程/多进程应用程序中的复杂性正是这样:识别一次必须由单个线程使用的资源并适当地锁定它们。 Linux 内核开发人员仍然会定期修复错误,这真的很难......
    • 此外,您已经处于这种情况:python 具有全局解释器锁,它只允许在所有线程中一次执行一条 python 指令。因此,只有在线程中使用阻塞 IO 调用时,您才会看到加速。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2015-04-21
    • 2019-07-07
    • 1970-01-01
    • 2012-03-31
    相关资源
    最近更新 更多