简体   繁体   English

需要Python线程帮助

[英]Python threading help Needed

I am snowblind from looking at examples that don't exactly fit my case ... or maybe they do. 我对那些不完全符合我的情况的例子视而不见...也许它们确实对。 So if there are great examples out there for this, I have not been able to interpret them with about 3 weeks of Python experience 因此,如果有很多很好的例子,那么我大约有3个星期的Python经验还无法解释它们。

I have a script that queries a database, gathers a list of downloadable movies, then downloads them to your chosen directory, one by one. 我有一个查询数据库的脚本,收集可下载电影的列表,然后将它们一个接一个地下载到您选择的目录中。 And I would like to make it download 4 or 5 at once, as it takes an age to do it. 我想让它一次下载4或5,因为要花一些时间才能完成。

Here is a simplified version what I have attempted to do, myapp is my database application. 这是我尝试做的简化版本,myapp是我的数据库应用程序。 However it appears to just run sequential, even though it says it's starting both threads 但是它似乎只是按顺序运行,即使它说它正在启动两个线程

listOfIDs are the ids of some containers that may or may not have movies, then versionS returns the movie file names. listOfIDs是某些可能带有或不带有电影的容器的ID,然后versionS返回电影文件名。

import threading
import myapp_api

listOfIDs = (14809, 14808, 14807, 14806, 14805, 14804, 14803)
for ID in listOfIDs:
    versionS = myapp.find_one('Version', [['id', 'is', ID]], ['uploaded_movie'])

ipath = ('/Users/me/Desktop/scripts/downloads/')

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name
        for ID in listOfIDs:
            print "\nID= " + str(ID) + "\n"
            downLoad(ID)
        print "Exiting " + self.name

def downLoad(ID):
    versionS = myapp.find_one('Version', [['id', 'is', ID]], ['uploaded_movie'])
    path = ipath + (str(versionS).split("'")[5])
    result = myapp.download_attachment(attachment=versionS['uploaded_movie'], file_path=path)
    print "Thread Name = " + threadName


# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)


# Start new Threads
thread1.start()
thread2.start()

print "Exiting Main Thread"

Ok, so I altered the code to take on the suggestion by ShadowRanger and it is still just downloading one at a time, have I stuffed this up somewhere? 好的,所以我更改了代码以接受ShadowRanger的建议,并且它仍一次只下载一个,是否可以在某个地方填充? ... code looks like this now. ...代码现在看起来像这样。

import threading
import myapp_api
from collections import deque

listOfIDs = (14809, 14808, 14807, 14806, 14805, 14804, 14803)
for ID in listOfIDs:
    versionS = myapp.find_one('Version', [['id', 'is', ID]], ['uploaded_movie'])

ipath = ('/Users/me/Desktop/scripts/downloads/')

def downLoad(ID):
    path = ipath + (str(versionS).split("'")[5])
    result = myapp.download_attachment(attachment=versionS['uploaded_movie'], file_path=path)

with closing(multiprocessing.Pool(4)) as pool:
    deque(pool.imap_unordered(downLoad, listOfIDs), maxlen=0)

And finally, All the advice by ShadowRanger was spot on, the error was in something I had done incorrectly (I think I was iterating over the listOfIDs early, and only passing the last one out to the function) ... here is the final working version. 最后, ShadowRanger所有建议ShadowRanger被发现了,错误在于我做错了某件事(我想我正在尽早遍历listOfID,并且只将最后一个传递给了函数)……这是最终的工作版本。

   import threading
    import myapp_api
    from collections import deque

listOfIDs = (14809, 14808, 14807, 14806, 14805, 14804, 14803)

ipath = ('/Users/me/Desktop/scripts/downloads/')

def downLoad(ID):
    versionS = myapp.find_one('Version', [['id', 'is', ID]], ['uploaded_movie'])
    path = ipath + (str(versionS).split("'")[5])
    result = myapp.download_attachment(attachment=versionS['uploaded_movie'], file_path=path)


with closing(multiprocessing.Pool(4)) as pool:
    deque(pool.imap_unordered(downLoad, listOfIDs), maxlen=0)

I don't see how the threads are splitting work. 我看不到线程如何拆分工作。 Looks like they both download the same set of things. 看起来他们俩都下载相同的东西。

If the goal is to download a bunch of files based on known IDs, multiprocessing has a .dummy module that can act like multiprocessing but implemented using threads, which gets you an easy thread pool: 如果目标是根据已知的ID下载一堆文件,则multiprocessing具有一个.dummy模块,该模块可以像multiprocessing一样工作,但使用线程来实现,从而为您提供了一个简单的线程池:

import multiprocessing.dummy as multiprocessing
from contextlib import closing

with closing(multiprocessing.Pool(4)) as pool: # Pick your favorite number of workers
    pool.map(downLoad, listOfIDs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM