在并发Python中创建一个进度计数器

时间:2014-04-20 18:49:21

标签: python

from multiprocessing import Process, Pool
from bs4 import BeautifulSoup

alreadyProcessedFile = 0.0
processLength = 0.0

def convertedFile(filePath):

    fileName = os.path.basename(filePath).split('.')[0]

    print("Total: "+str(processLength)+", current: "+str(alreadyProcessedFile)
          + ", percentage: "+ str((alreadyProcessedFile+1.0)/(processLength+1)))

    #business logic

    print("One file is saved at the location: "+r'E:\xxx\SECProject\ProcessedSEC10KFiles\2012QTR1/'+fileName+'-finalDoc.txt')

def getFilePath(path):
    return glob.glob(os.path.join(path, '*.txt'))

if __name__ == '__main__':
    s = r"E:\xxx\SECProject\SEC10KFiles\2012QTR1"
    fileList = getFilePath(s)
    processLength = len(fileList)
    p = Pool(40)
    p.map(convertedFile, fileList)

这基本上是python程序的缩短版本。我没有外面的包装课,我想在里面有一个计数器来跟踪进度(所以我知道程序什么时候停止)。但是,该程序(def covertedFile()在访问已更改的变量时遇到问题:alreadyProcessedFileprocessLength

我知道并发可能会遇到共享状态问题,但是如何在没有某种程度的共享状态的情况下完成计数器?为什么并发函数不能访问它之外的变量呢?


同样可能听起来很奇怪,这个并发版本程序无法处理一个目录下的所有文件(大约5000个)。我想知道程序是否在某些进程仍在运行时关闭。这有可能吗?

1 个答案:

答案 0 :(得分:0)

multiprocessing在您启动新进程时为每个进程创建内存的副本。通过模块级全局变量共享状态并不起作用,因为每个进程都拥有它自己的"快照"在你分叉过程时的全局变量。改变一个流程'全局变量并没有神奇地传播到其他过程。

如果您需要在进程之间共享状态,则需要使用multiprocessing给您的一个工具。您可以通过ValueArray分享c类型,也可以使用Manager分享任意数据类型。有关详细信息和示例,请参阅文档中的sharing state between processes