Python多处理/线程阻塞主线程

时间:2014-04-11 15:40:41

标签: python multithreading multiprocessing

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

线程示例:

#!/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()

我想要的是这些程序立即打印“启动程序”(在Web浏览器中),然后几秒钟后,文本文件显示在我给予写入权限的目录中。然而,实际发生的是它们在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可执行文件运行)

1 个答案:

答案 0 :(得分:0)

好的 - 我想我找到了答案。部分原因是我自己的误解。 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函数来启动工作脚本而不是exec函数,这总是让我感到不舒服。