使用workerpool模块的多线程

0 投票
1 回答
663 浏览
提问于 2025-04-17 00:23
import os
import urllib
import workerpool

from datetime import datetime

class DownloadJob(workerpool.Job):    

    def __init__(self, fa):
       self.fa = fa 

    def run(self):        
       f = open(self.fa + '.txt','w')
       f.write('Example Note.......')
       f.close()  


pool = workerpool.WorkerPool(size=5)

def workfile():        
    range1 = 51
    range2 = 102
    fam1 = 555
    fam2 = 833

    ranges = range2 -range1
    fams = fam2 -fam1
    workname = "Python"

    path = os.getcwd()

    os.system('mkdir ' + str(workname))
    sTime = datetime.now()

    for a in range(ranges + 1):
        os.chdir(path + '\\' + str(workname))
        os.system('mkdir ' + str(range1 + a))
        os.chdir(path + '\\' + str(workname) + '\\' + str(range1 + a))

        for b in range(fams + 1):
            fa = str(fam1 + b)
            job = DownloadJob(fa)
            pool.put(job)
            pool.shutdown()
            pool.wait()                                              

        print 'Elapsed Time: %s' % (datetime.now() - sTime)

        z = open('info.txt','w')
        z.write('Elapsed Time: %s' % (datetime.now() - sTime))
        z.close()

    os.chdir(path + '\\' + str(workname))

    tumSure = open('info.txt','w')
    tumSure.write('Elapsed All Time: %s' % (datetime.now() - sTime))
    tumSure.close()

    print 'All Time: %s' % (datetime.now() - sTime)        
    print 'Workname : %s downloaded.' % (workname)

    quit()

workfile()

大家好,

我有一段代码,想用线程的方式来创建文件。文件夹的编号从 range1 开始,也就是51。然后在这个目录下会创建一些文本文件,名字从 555.txt833.txt。但是在创建名为 52 的文件夹后,它就停止了,没法继续创建 555.txt833.txt 的文件。

我觉得它停止的原因是

pool.shutdown()
pool.wait()

我该怎么做才能让这个循环不停下来呢?

1 个回答

3

我觉得只有在你完全用完这个池子的时候,才应该关闭它,也就是说在 for a 循环结束后,最好放在一个 try...finally 结构里。

这样写的话,代码看起来会是这样的:

try:
    for a in range(ranges + 1):
        os.chdir(path + '\\' + str(workname))
        os.system('mkdir ' + str(range1 + a))
        os.chdir(path + '\\' + str(workname) + '\\' + str(range1 + a))

        for b in range(fams + 1):
            fa = str(fam1 + b)
            job = DownloadJob(fa)
            pool.put(job)
finally:
    pool.shutdown()
    pool.wait()

这样的话,pool 的关闭

a) 只会在所有的池子操作完成后进行,并且 b) 即使出现了错误,也会确保能干净利落地关闭。

如果这个池子有一个上下文管理器,那就更简单了。不过据我所知,它是没有的。 否则,你可以这样做:

with pool:
    for a in range(ranges + 1):
        os.chdir(path + '\\' + str(workname))
        os.system('mkdir ' + str(range1 + a))
        os.chdir(path + '\\' + str(workname) + '\\' + str(range1 + a))

        for b in range(fams + 1):
            fa = str(fam1 + b)
            job = DownloadJob(fa)
            pool.put(job)

不过如果你愿意的话,你也可以这样做:

from contextlib import contextmanager

@contextmanager
def shutdown_wait(pool):
    try:
        yield pool
    finally:
        pool.shutdown()
        pool.wait()

...
with shutdown_wait(pool):
    for a ... [as above]

撰写回答