为什么python进程与barrier.wait()的行为不同?

时间:2018-07-24 17:56:39

标签: python python-3.x multiprocessing python-multiprocessing barrier

TLDR

选择从0返回barrier.wait()的进程将在下一次迭代中偏移进程的顺序。为什么?

全文

以下问题是我实际问题的简单版本。

可以说我有以下多重处理问题: 我有一个字符串(命名为输出),n个进程,n个字符(非空格)和N次迭代。

示例:output, n, characters, N = '', 3, ['a', 'b', 'c'], 4

对于每次迭代,每个进程都应将其字符附加到字符串(以任何顺序)。每次迭代后,都应在字符串后附加一个空格字符。

对于该示例,输出可能是: output = 'bca abc bac cab'

要获得此功能,我使用多处理库。

from multiprocessing import Process, Lock, Value, Manager, Barrier
import ctypes

def print_characters(lock, barrier, character, N, output):
    for i in range(N):
        lock.acquire()
        output.value += character
        lock.release()
        _id = barrier.wait() # get an id for each thread (although not promised to be assigned randomly)
        if _id == 0: # select 1 and get this thread to append the ' '
            lock.acquire()
            output.value += ' '
            lock.release()
        barrier.wait()

if __name__ == '__main__':
    manager = Manager()
    output = manager.Value(ctypes.c_char_p, "")
    num_processes = 3
    characters = 'abc'
    N = 4

    lock, barrier  = Lock(), Barrier(num_processes)
    processes = []

    for i in range(num_processes):
        p = Process(target=print_characters, args=(lock, barrier, characters[i], N, output))
        p.start()
        processes.append(p)
    for p in processes:
        p.join()

    print(output.value)

很酷。...

根据Barrier.wait()的文档

  

屏障的所有[process]都调用了此函数后,它们会同时释放。

因此,如果同时释放所有n进程,我想知道这是否会在进程上引起某种“统一随机竞争条件”,从而使每个进程都有平等的机会进入{{1 }}。

我不太在意订单,但是很高兴知道我将来的流程是否有所不同。

要查看是否是这种情况,我计算了每个字符到达该位置的次数:

lock.acquire()

对于N = 1000,这是我得到的一个输出:

output = output.value.split(' ')[:-1]
c = [[0]*num_processes for i in range(num_processes)]
for line in output:
    for i, character in enumerate(line):
        ind = characters.find(character)
        c[ind][i] += 1
print(c)

:|好吗?

因此,在1000次迭代中,具有第一个字符的过程始终是第一位。这似乎不是很随机。

然后我在[[1000 0 0] [ 0 948 52] [ 0 52 948]] 函数中进行了一项更改:

print_characters

然后我得到了

if _id == 1:

不是均匀随机的,但也没有偏见。

更改进程数(假设cpu可以支持它),因此字符数显示出相同的效果:

选择从[[254 254 492] [489 489 22] [257 257 486]] 返回0的进程会在下一次迭代时偏置进程的顺序。

为什么?

0 个答案:

没有答案