我写了一些代码,如:
import threading
import httplib2
import time
class Download(threading.Thread):
def __init__(self, url, location):
super(Download, self).__init__()
self.url = url
self.location = location
self.http = httplib2.Http()
def download(self):
resp, content = self.http.request(self.url)
with open(self.location, "wb") as f:
f.write(content)
def run(self):
self.download()
p = Download("http://www.wswd.net/testdownloadfiles/1GB.zip","/tmp/1GB.zip")
p.start()
它可以与Django一起使用,立即返回并在后台下载,一切都很好。
但不要在终端中工作,例如:
python test.py
睡眠10分钟后即可开始下载。
为什么?
非常感谢!
很抱歉让您误解,我删除了time.sleep(10)
行并将PNG文件更改为一个大的EXE文件。
可以立即返回,并在后台下载Django。
但当我运行时,它被阻止并等待下载完成:
python test.py
在终端
我不知道为什么.....
有人删除了我正在阅读的第二个答案.....
答案 0 :(得分:4)
它在终端中工作,但Python进程本身必须托管所有线程,因此在所有线程完成运行之前它不能退出。这是一个可视化:
[1] [2] [4]
+------+---+
\
'-+-----------------------------+
[3] [5]
\ /
'------- Python process lifespan ------'
活动:
它在Django中工作的原因是因为Django的主线程总是忙于等待更多的工作,但这并不意味着你的线程无效。
要解决此问题并在后台实际下载,您可以使用python yourfile.py &
在终端上启动python(注意&符号),也可以使用Popen
生成一个未附加到的新Python进程主要进程,将在Python从终端关闭后继续。
P.S。:我对ASCII艺术不好,不要嘲笑我。
答案 1 :(得分:0)
默认情况下,Python进程将等待所有非守护程序线程退出,然后再返回到提示符。如果将print("Bye!")
添加到脚本的末尾,您将看到它打印但仍然会在返回提示之前延迟。这是因为您的下载线程还没有完成,Python正在等待它完成。另一方面,如果您将线程创建为守护程序线程,Python进程将立即退出并终止正在运行的线程,从而使您部分下载 - 如果是这样,因为它会很快退出。
如果您希望将代码作为后台进程运行,那么您有一些选择。首先,你不需要一个单独的线程 - 你可以在shell中在后台运行它,如果你是在Unix风格的系统上:
python test.py &
&
表示要在后台启动该过程。
在Unix环境中,另一种方法是将Python代码置于后台。我不会在这里详细介绍所有细节,但可以找到一个很好的机制来编写在后台运行的守护进程here。
使用Django,你不必担心这个问题,因为它是一个漫长的过程并等待更多的工作。