Python的 - 使用线程或队列遍历一个for循环调用一个函数(Python - Using th

2019-09-24 01:46发布

我是相当新的Python和我做一个脚本,允许从其他程序到Autodesk Maya中带来的点云数据。 我有我的脚本运行正常,但我想要做的是让它更快。 我有一个for循环,通过编号的文件列表进行迭代。 即datafile001.txt,datafile002.txt等。 是我不知道是如果有办法把它做一个以上的时间,可能使用的线程或队列? 下面我有我一直在努力的代码:

     def threadedFuntion(args):
         if len(sourceFiles) > 3:
             for count, item in enumerate(sourceFiles):
                     t1=Thread(target=convertPcToPdc,args=(sourceFiles[filenumber1], particlesName, startframe, endframe, pdcIncrements, outputDirectory, variableFolder, acceptableArrayforms, dataType))
                     t1.start()
                     t2=Thread(target=convertPcToPdc,args=(sourceFiles[filenumber2], particlesName, startframe, endframe, pdcIncrements, outputDirectory, variableFolder, acceptableArrayforms, dataType))
                     t2.start()
                     t3=Thread(target=convertPcToPdc,args=(sourceFiles[filenumber3], particlesName, startframe, endframe, pdcIncrements, outputDirectory, variableFolder, acceptableArrayforms, dataType))
                     t3.start()
                     t4=Thread(target=convertPcToPdc,args=(sourceFiles[filenumber4], particlesName, startframe, endframe, pdcIncrements, outputDirectory, variableFolder, acceptableArrayforms, dataType))
                     t4.start()

这显然不会为一些原因的工作,首先它只是将创建4个线程,我希望能够给一个选项,更多或更少。 其次,它的错误,因为它试图重新使用一个线程? 就像我说的我是很新的Python和我有点在我头上,我一直在阅读这里的几个职位,但不能得到一个工作非常正确。 我认为,一个队列可能是一些我需要的,但不能完全弄清楚,我试验了条件语句,并与连接语句,但再次无法得到我想要的东西。

我想更具体的我想达到的目标是,该功能通过读取一个文本文件,检索COORDS然后它们导出为一个二进制文件的玛雅阅读。 这是常见的这些文本文件之一,有5-10万的x,y,这需要相当长的一段时间žCOORDS。 它需要大约30分钟,1小时做一个非常残忍的计算机上1个文件,任务经理说,Python是只使用12%的处理器和1%左右的内存,所以如果我能同时做的这些多重,它将使做这些100或多个文件去了快了很多。 我不认为这将是很难多线程/排队一个for循环,但我一直在一个星期左右消失,努力未能解决。

谢谢大家的帮助,我真的很感激,并认为这个网站是惊人的。 这是我的第一篇文章,但我觉得我已经完全只是从这里阅读上了解到蟒蛇。

Answer 1:

子类threading.Thread并把你的功函数在该类作为运行的一部分()。

import threading
import time
import random

class Worker(threading.Thread):
    def __init__(self, srcfile, printlock,**kwargs):
        super(Worker,self).__init__(**kwargs)
        self.srcfile = srcfile
        self.lock = printlock # so threads don't step on each other's prints

    def run(self):
        with self.lock:
            print("starting %s on %s" % (self.ident,self.srcfile))
        # do whatever you need to, return when done
        # example, sleep for a random interval up to 10 seconds
        time.sleep(random.random()*10)
        with self.lock:
            print("%s done" % self.ident)


def threadme(srcfiles):
    printlock = threading.Lock()
    threadpool = []
    for file in srcfiles:
        threadpool.append(Worker(file,printlock))

    for thr in threadpool:
        thr.start()

    # this loop will block until all threads are done
    # (however it won't necessarily first join those that are done first)
    for thr in threadpool:
        thr.join()

    print("all threads are done")

if __name__ == "__main__":
    threadme(["abc","def","ghi"])

按照要求,以限制线程数,使用以下命令:

def threadme(infiles,threadlimit=None,timeout=0.01):
    assert threadlimit is None or threadlimit > 0, \
           "need at least one thread";
    printlock = threading.Lock()
    srcfiles = list(infiles)
    threadpool = []

    # keep going while work to do or being done
    while srcfiles or threadpool:

        # while there's room, remove source files
        # and add to the pool
        while srcfiles and \
           (threadlimit is None \
            or len(threadpool) < threadlimit):
            file = srcfiles.pop()
            wrkr = Worker(file,printlock)
            wrkr.start()
            threadpool.append(wrkr)

        # remove completed threads from the pool
        for thr in threadpool:
            thr.join(timeout=timeout)
            if not thr.is_alive():
                threadpool.remove(thr)

    print("all threads are done")

if __name__ == "__main__":
    for lim in (1,2,3,4):
        print("--- Running with thread limit %i ---" % lim)
        threadme(("abc","def","ghi"),threadlimit=lim)

请注意,这实际上将处理反向源(由于列表弹出())。 如果你需要他们为了完成某处扭转列表,或者使用双端队列和popleft()。



Answer 2:

我会建议使用mrjob这一点。

工作先生是一个Python实现地图降低 。

下面是先生的工作代码做一个多线程的字数超过了很多的文本文件:

from mrjob.job import MRJob

class MRWordCounter(MRJob):
    def get_words(self, key, line):
        for word in line.split():
            yield word, 1

    def sum_words(self, word, occurrences):
        yield word, sum(occurrences)

    def steps(self):
        return [self.mr(self.get_words, self.sum_words),]

if __name__ == '__main__':
    MRWordCounter.run()

此代码的所有文件映射并联(计数每个文件的话),则减小了的各种计数到一个单一的总字数。



文章来源: Python - Using threads or a queue to iterate over a for loop that calls a function