python - 如何在 Python WSGI 服务器中实现多线程

标签 python concurrency webserver

只是预先澄清这只是一个学习项目,我无意在生产中使用它。已经有几个非常好的 Python 应用程序服务器了。但我想了解更多关于并发的知识,所以我开始写一篇(我认为)我知道的东西。

此外,因为我想“更接近金属”,所以我一开始只使用 Socket,并希望保持这种状态。

以下是我迄今为止所掌握的重要部分。 self.iq 是一个 Queue 对象 (inbound_queue),它实际上不执行任何操作,而是将请求(包括套接字对象)放入 outbound_queue,然后 Consumer 对象从 outbound_queue 获取请求并将其传递给 ResponseHandler。这似乎只要我击中它就可以很好地工作,但我担心我会通过幼稚的实现让自己陷入竞争条件。具体将特定于请求的事物分配给 ServerClass 对象。

所以问题是:有没有更好的方法来做到这一点,或者我的队列使用是否会阻止两个线程拾取并操作同一个对象?我是否应该将诸如 WSGI 环境之类的东西封装到一个单独的对象中,该对象也可以传递到队列中?由于需要传入回调函数,因此在尝试编写符合 WSGI 的服务器时,执行此类操作会变得很棘手。

class Consumer(threading.Thread):

    def __init__(self, out_queue, server):
        threading.Thread.__init__(self)
        self.out_queue = out_queue
        self.server = server

    def run(self):
        while True:
        item = self.out_queue.get()
        self.server.ResponseHandler(self.server, item)
        self.out_queue.task_done()

class QueueConsumerServer(object):

    methods_allowed = ['get', 'post', 'put', 'patch', 'delete', 'options', 'upgrade']

    def __init__(self, host, port, application):
        self.host = host
        self.port = port
        self.application = application
        self.iq = Queue.Queue()
        self.oq = Queue.Queue()

        self.socket = socket.socket()
        self.socket.bind((self.host, self.port))
        #<snip of lots of assigning stuff to environ>
        self.environ = environ
        headers_set = []
        headers_sent = []
        for i in xrange(3):
            thr = Producer(self.iq, self.oq)
            thr.daemon = True
            thr.start()

        for i in xrange(3):
            thr = Consumer(self.oq, self)
            thr.daemon = True
            thr.start()


    def handle_request(self):
        self.socket.listen(1)
        try:
            while True:
                cli, addr = self.socket.accept()
                data = cli.recv(1024)
                request_data = self.parse_request_data(data)
                req.path = request_data[1]
                req.cli = cli
                self.iq.put(req)
                return
        except Exception, ex:
            print 'e', ex,
            sys.exit(1)
        finally:
            sys.stdout.flush()
            self.socket.close()

最佳答案

Python 队列是 thread safe ,因此您编写的代码中不存在竞争。

关于解决此问题的更好方法,您的代码可能会达到 GIL不久。我建议查看 multiprocessing .

关于python - 如何在 Python WSGI 服务器中实现多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16901397/

相关文章:

Python 3 : subprocess causes zombies

python - getch() 在打印之前获取输入

python - 如何使用奇点图像运行 jupyter 笔记本?

concurrency - 重用 Go channel 会导致死锁

hibernate - 在 Grails 中使用 GORM 时的并发性

linux - SonarQube 返回错误的网关错误

python - 如何将虚拟环境从服务器复制/克隆到本地计算机

python - 是否可以将列表转换为键的嵌套字典*而无需*递归?

java - Fork 和 Join 特性 jdk7 线程数

macos - Mac OS X - 如何将 Web 项目存储在/Library 以外的位置