【问题标题】:Call to POpen inside thread that is running along side WSGIREF.simple_server causes deadlock on os.fork在 WSGIREF.simple_server 旁边运行的线程内部调用 POpen 会导致 os.fork 死锁
【发布时间】:2012-09-26 22:41:01
【问题描述】:

此问题与A Django Related Question有关

我正在使用 wsgiref.simple_server 运行一个 restlite WSGI 应用程序。我有这个设置,以便在 serve_forever() 方法被调用之前它初始化一些对象。最相关的是这些课程。

import Queue
import threading
import Deployer
import ParallelRunner
import sys
import subprocess

class DeployManager:
def __init__(self):
    self.inputQueue = Queue.Queue() 
    self.workerThread = DeployManagerWorkerThread(self.inputQueue)
    self.workerThread.start()   
def addDeployJob(self, appList):
    self.inputQueue.put(appList)  #make sure this handles the queue being full
def stopWorker(self):
    self.workerThread.running = False
def __del__(self):
    self.stopWorker()

class DeployManagerWorkerThread(threading.Thread):
def __init__(self, Queue):
    super(DeployManagerWorkerThread, self).__init__()
    self.queue = Queue
    self.running = True
    self.deployer = Deployer.Deployer()
    self.runner = ParallelRunner.ParallelRunner()

def run(self):
    while self.running:
        try:
            appList = self.queue.get(timeout = 10) #This blocks until something is in the queue
            sys.stdout.write('Got deployment job\n')
                            command = "ssh " + server.sshUsername + "@" + server.hostname + "" + " -i " + server.sshPrivateKeyPath + r" 'bash -s' < " + pathToScript 
                            self.process = subprocess.Popen(command,shell=True ,stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            output = process.communicate()[0]
            sys.stdout.write(output + '\n')
        except Queue.Empty:
            pass
    sys.stdout.write('DeployManagerWorkerThread exiting\n')

restlite请求是这样设置的

@restlite.resource
def deployAll():
def POST(request, entity):
    GlobalDeployManager.addDeployJob(GlobalAppList) #TODO should runners be configurable at start up
    #print output                                               #or on a run by run basis
    return 'Job added'
return locals()

这会将一个条目放入队列中,然后 workerThread 将抓取并开始处理。然而,对 POpen 的调用总是挂起,我介入了这个,它似乎挂在对 os.fork() 的调用,这将“冻结”服务器。当线程到达 POpen 命令时,主线程位于它接受新请求的行。我相信服务器正在为此使用 epoll。如果队列中有多个作业,我可以在服务器正在运行的控制台上按 control-C,主线程将退出(不在等待请求的行),然后线程将能够运行按预期工作,然后关闭。有什么想法吗?

【问题讨论】:

    标签: python rest fork wsgi popen


    【解决方案1】:

    我最终想通了……我需要在 run 方法中创建线程对象。我不小心忘记了 init 方法是从主线程调用的,然后新线程本身永远不会执行 init

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多