python线程不起作用

时间:2015-01-27 08:45:39

标签: python django multithreading

我写了一些代码,如:

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

在终端

我不知道为什么.....


有人删除了我正在阅读的第二个答案.....

2 个答案:

答案 0 :(得分:4)

它在终端中工作,但Python进程本身必须托管所有线程,因此在所有线程完成运行之前它不能退出。这是一个可视化:

[1]    [2] [4]
 +------+---+
        \
         '-+-----------------------------+
          [3]                           [5]


\                                        /
 '------- Python process lifespan ------'

活动:

  1. Python启动,运行导入和类定义
  2. 您的主题开始
  3. 在辅助线程上下载初学者
  4. 主线程没有更多事情要做,退出
  5. 下载完成,存在辅助线程
  6. 它在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,你不必担心这个问题,因为它是一个漫长的过程并等待更多的工作。