进程间共享内存
shared memory between processes
我正在研究 python 中的多处理模块,并尝试并行化一个算法,该算法每次循环具有不同增量值的列表(Sieve of Eratosthenes 算法的修改)。因此,我希望在所有进程之间有一个共享列表,以便所有进程都修改同一个列表。我已经尝试使用 multiprocessing.Array
函数,但是当我到达程序末尾时,数组仍未修改并且仍然包含所有 0(我将其初始化为的值)。
import multiprocessing
import math
num_cores = multiprocessing.cpu_count()
lower = 0
mark = None
def mark_array(k):
global mark
index = (-(-lower//k)*k)-lower
for i in range(index, len(mark), k):
mark[i] = 1
def sieve(upper_bound, lower_bound):
size = upper_bound - lower_bound + 1
global mark
mark = multiprocessing.Array('i', size, lock=False)
for i in range(size):
mark[i] = 0
klimit = int(math.sqrt(upper_bound)) + 1
global lower
lower = lower_bound
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=num_cores)
inputs = list(range(2, klimit+1))
pool.map(mark_array, inputs)
pool.close()
pool.join()
result = []
for i in range(size):
result.append(mark[i])
print(result)
sieve(200,100)
请原谅代码。有点乱,但我只是想在清理之前让共享内存正常工作。
编辑: 好的,所以我在 linux 机器上尝试了完全相同的代码,在那里我得到了预期的输出。但是,运行 Windows 机器上的 VS 代码中的相同代码不会。知道为什么吗?
EDIT#2: 这似乎是一个 Windows 特定问题,因为 Windows OS 处理流程的方式不同于 Linux.如果是这种情况,知道如何解决吗?
您可以尝试使用 multiprocessing.Manager 来完成您的任务:
import multiprocessing
import math
from functools import partial
num_cores = multiprocessing.cpu_count()
lower = 0
def mark_array(mark, k):
index = (-(-lower // k) * k) - lower
for i in range(index, len(mark), k):
mark[i] = 1
def sieve(upper_bound, lower_bound):
size = upper_bound - lower_bound + 1
klimit = int(math.sqrt(upper_bound)) + 1
global lower
lower = lower_bound
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=num_cores)
with multiprocessing.Manager() as manager:
mark = manager.list(range(size))
for i in range(size):
mark[i] = 0
inputs = list(range(2, klimit + 1))
foo = partial(mark_array, mark)
pool.map(foo, inputs)
pool.close()
pool.join()
result = []
for i in range(size):
result.append(mark[i])
print(result)
sieve(200, 100)
我正在研究 python 中的多处理模块,并尝试并行化一个算法,该算法每次循环具有不同增量值的列表(Sieve of Eratosthenes 算法的修改)。因此,我希望在所有进程之间有一个共享列表,以便所有进程都修改同一个列表。我已经尝试使用 multiprocessing.Array
函数,但是当我到达程序末尾时,数组仍未修改并且仍然包含所有 0(我将其初始化为的值)。
import multiprocessing
import math
num_cores = multiprocessing.cpu_count()
lower = 0
mark = None
def mark_array(k):
global mark
index = (-(-lower//k)*k)-lower
for i in range(index, len(mark), k):
mark[i] = 1
def sieve(upper_bound, lower_bound):
size = upper_bound - lower_bound + 1
global mark
mark = multiprocessing.Array('i', size, lock=False)
for i in range(size):
mark[i] = 0
klimit = int(math.sqrt(upper_bound)) + 1
global lower
lower = lower_bound
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=num_cores)
inputs = list(range(2, klimit+1))
pool.map(mark_array, inputs)
pool.close()
pool.join()
result = []
for i in range(size):
result.append(mark[i])
print(result)
sieve(200,100)
请原谅代码。有点乱,但我只是想在清理之前让共享内存正常工作。
编辑: 好的,所以我在 linux 机器上尝试了完全相同的代码,在那里我得到了预期的输出。但是,运行 Windows 机器上的 VS 代码中的相同代码不会。知道为什么吗?
EDIT#2: 这似乎是一个 Windows 特定问题,因为 Windows OS 处理流程的方式不同于 Linux.如果是这种情况,知道如何解决吗?
您可以尝试使用 multiprocessing.Manager 来完成您的任务:
import multiprocessing
import math
from functools import partial
num_cores = multiprocessing.cpu_count()
lower = 0
def mark_array(mark, k):
index = (-(-lower // k) * k) - lower
for i in range(index, len(mark), k):
mark[i] = 1
def sieve(upper_bound, lower_bound):
size = upper_bound - lower_bound + 1
klimit = int(math.sqrt(upper_bound)) + 1
global lower
lower = lower_bound
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=num_cores)
with multiprocessing.Manager() as manager:
mark = manager.list(range(size))
for i in range(size):
mark[i] = 0
inputs = list(range(2, klimit + 1))
foo = partial(mark_array, mark)
pool.map(foo, inputs)
pool.close()
pool.join()
result = []
for i in range(size):
result.append(mark[i])
print(result)
sieve(200, 100)