Mah*_* Ra 2 python multithreading multiprocessing
我有一个用 python 编写的程序,它读取 4 个输入文本文件并将它们全部写入一个名为的列表,该列表ListOutput是我的程序中使用的 4 个进程之间的共享内存(我使用了 4 个进程,因此我的程序运行得更快!)
我还有一个名为的共享内存变量processedFiles,它存储任何进程已读取的输入文件的名称,因此当前进程不会再次读取它们(我使用了锁,因此进程不会processedFiles同时检查内部文件是否存在时间)。
当我只使用一个进程时,我的程序运行得更快(7 毫秒)——我的计算机有 8 个内核。为什么是这样?
import glob
from multiprocessing import Process, Manager,Lock
import timeit
import os
os.chdir("files")
# Define a function for the Processes
def print_content(ProcessName,processedFiles,ListOutput,lock):
for file in glob.glob("*.txt"):
newfile=0
lock.acquire()
print "\n Current Process:",ProcessName
if file not in processedFiles:
print "\n", file, " not in ", processedFiles," for ",ProcessName
processedFiles.append(file)
newfile=1 #it is a new file
lock.release()
#if it is a new file
if newfile==1:
f = open(file,"r")
lines = f.readlines()
ListOutput.append(lines)
f.close()
#print "%s: %s" % ( ProcessName, time.ctime(time.time()) )
# Create processes as follows
try:
manager = Manager()
processedFiles = manager.list()
ListOutput = manager.list()
start = timeit.default_timer()
lock=Lock()
p1 = Process(target=print_content, args=("Procees-1",processedFiles,ListOutput,lock))
p2 = Process(target=print_content, args=("Process-2",processedFiles,ListOutput,lock))
p3 = Process(target=print_content, args=("Process-3",processedFiles,ListOutput,lock))
p4 = Process(target=print_content, args=("Process-4",processedFiles,ListOutput,lock))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()
print "ListOutput",ListOutput
stop = timeit.default_timer()
print stop - start
except:
print "Error: unable to start process"
Run Code Online (Sandbox Code Playgroud)
问题在于,看似多处理的东西通常并非如此。仅仅使用更多的核心并不意味着做更多的工作。
最明显的问题是你要同步一切。选择文件是连续的,因为您锁定了,所以这里的增益为零。当您并行读取时,读取的每一行都会写入共享数据结构 - 该结构将在内部同步自身。因此,你可能获得的唯一收获就是并行阅读。根据您的介质(例如 HDD 而不是 SSD),多个读取器的总和实际上比单个读取器慢。
最重要的是管理所有这些流程的开销。每一项都需要开始。每个都需要传递其输入。每个人都必须与其他人沟通,这几乎发生在每一个行动中。不要被愚弄了,aManager很漂亮但很重量级。
因此,除了获得很少的收益之外,还增加了额外的成本。由于您一开始的运行时间非常小7ms,因此额外的成本可能相当可观。
一般来说,multiprocessing只有当您受 CPU 限制时才值得。也就是说,您的 CPU 效率接近 100%,即工作量超出了所能完成的工作量。通常,当您进行大量计算时会发生这种情况。通常,主要执行 I/O 是一个很好的指标,表明您不受CPU限制。