【问题标题】:Python multiprocessing/threading blocking main threadPython多处理/线程阻塞主线程
【发布时间】:2014-05-25 20:51:12
【问题描述】:

我正在尝试用 Python 编写程序。我要编写的是一个脚本,它会立即向用户返回一条友好的消息,但会在后台生成一个长子进程,该子进程带有几个不同的文件并将它们写入一个祖父文件。我已经完成了几个关于线程和处理的教程,但我遇到的是,无论我尝试什么,程序都会等待并等待子进程完成,然后才会向用户显示上述友好消息。这是我尝试过的:

线程示例:

#!/usr/local/bin/python
import cgi, cgitb
import time
import threading

class TestThread(threading.Thread):
     def __init__(self):
         super(TestThread, self).__init__()

     def run(self):
        time.sleep(5)
        fileHand = open('../Documents/writable/output.txt', 'w')
        fileHand.write('Big String Goes Here.')
        fileHand.close()

print 'Starting Program'

thread1 = TestThread()
#thread1.daemon = True
thread1.start()

我已经阅读了这些关于多线程的 SO 帖子 How to use threading in Python? running multiple threads in python, simultaneously - is it possible? How do threads work in Python, and what are common Python-threading specific pitfalls?

最后一个说在 Python 中同时运行线程实际上是不可能的。很公平。这些帖子中的大多数还提到了多处理模块,所以我已经阅读了它,它看起来相当简单。以下是我找到的一些资源:

How to run two functions simultaneously Python Multiprocessing Documentation Example https://docs.python.org/2/library/multiprocessing.html

下面是翻译成多处理的同一个例子:

#!/usr/local/bin/python
import time
from multiprocessing import Process, Pipe

def f():
    time.sleep(5)
    fileHand = open('../Documents/writable/output.txt', 'w')
    fileHand.write('Big String Goes Here.')
    fileHand.close()

if __name__ == '__main__':
    print 'Starting Program'
    p = Process(target=f)
    p.start()

我想要这些程序立即打印“启动程序”(在网络浏览器中),然后几秒钟后,一个文本文件出现在我授予写入权限的目录中。然而,实际发生的情况是它们都没有响应 5 秒钟,然后它们打印“正在启动程序”并同时创建文本文件。我知道我的目标是可能的,因为我在 PHP 中使用了这个技巧:

//PHP
exec("php child_script.php > /dev/null &");

我认为这在 Python 中是可能的。如果我遗漏了一些明显的东西,或者我以完全错误的方式考虑这个问题,请告诉我。感谢您的宝贵时间!

(系统信息:Python 2.7.6,Mac OSX Mavericks。Python 使用自制软件安装。我的 Python 脚本在 Apache 2.2.26 中作为 CGI 可执行文件运行)

【问题讨论】:

  • 您可能遇到了 GIL 问题。我已经在自己的程序中通过继承multiprocessing.Process 类而不是threading.Thread 克服了这个问题,并且有效。我不打电话给p = Process(target=f)
  • 还有一段时间后它显示“正在启动程序”的事实可能是由于标准输出缓冲。尝试使用 sys.stdout.flush()

标签: python multithreading multiprocessing


【解决方案1】:

好的-我想我找到了答案。部分原因是我自己的误解。 python 脚本不能简单地将消息返回到客户端 (ajax) 程序,但仍会执行一个大进程。响应客户端的行为本身就意味着程序已经完成,线程等等。那么,解决方案就是使用这个 PHP 技巧的 Python 版本:

//PHP
exec("php child_script.php > /dev/null &");

在 Python 中:

#Python
subprocess.call(" python worker.py > /dev/null &", shell=True)

它在当前进程之外开始一个全新的进程,并且在当前进程结束后继续。我会坚持使用 Python,因为至少我们使用文明的 api 函数来启动 worker 脚本,而不是 exec 函数,这总是让我感到不舒服。

【讨论】:

    猜你喜欢
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 2016-09-25
    • 2012-06-11
    • 2015-12-29
    • 1970-01-01
    相关资源
    最近更新 更多