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
的进程会在下一次迭代时偏置进程的顺序。
为什么?