线程阻塞主线程

Thread blocks the main thread

我不是 python 程序员。 但是我需要为 Openstack Swift 编写中间件。我不知道代码运行在什么环境。我无法控制主线程。

我很想启动将为队列服务的子线程,但该线程阻塞了主线程。 主线程打印 1 并挂起。按Ctrl+C继续执行,但子线程停止。

去哪里挖?

class ProxyLoggingMiddleware(object):
    """
    Middleware that logs Swift proxy requests in the swift log format.
    """

    def __init__(self, app, conf, logger=None):
        self.queue = Queue(0)
        print "1\n"
        self.processor = self.init_queue_processor()
        print "2\n"


    def init_queue_processor(self):
        processor = threading.Thread(target=self.process_queue, args=(self.fifo_pipe_pathname, self.queue, self.logger))
        processor.setDaemon(True)
        processor.start()
        return processor

    @staticmethod
    def process_queue(fifo_pipe_pathname, queue, logger):
        json_encoder = json.JSONEncoder()
        while True:
            stat = queue.get(True) # <----------------------- Blocks here

更新: 我在中间件中添加下一个代码,它打印 1, 2, 3

def m():
    print "--1\n"
    time.sleep(3)
    print "--2\n"


t = threading.Thread(target=m)
t.daemon = True
t.start()

print "--3\n"

但应该 1 3 2

仅当此代码运行在 Openstack Swift 环境中时才会出现问题!

UPD2:

/opt/swift # python --version
Python 2.7.18
/opt/swift # uname -a
Linux 45cefc56fd0a 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021 x86_64 Linux

UPD3:

我更新了我的代码

    def __init__(self, app, conf, logger=None):

        print threading.currentThread()
        self.processor = self.init_queue_processor()

    def init_queue_processor(self):
        processor = threading.Thread(target=self.process_queue, args=(self.fifo_pipe_pathname, self.queue, self.logger))
        processor.setDaemon(True)
        processor.start()
        return processor

    @staticmethod
    def process_queue(fifo_pipe_pathname, queue, logger):
        print threading.currentThread()
        json_encoder = json.JSONEncoder()
        while True: ....

输出为

/opt/swift # /usr/bin/python /usr/local/bin/swift-proxy-server /etc/swift/proxy-server.conf
<_MainThread(MainThread, started 140613464898888)>


<_MainThread(MainThread, started 140613464898888)>

我看到 process_queue 在主线程中执行。

如果队列中没有数据等待,则调用 queue.get(False) 将引发异常(空)。

没有显示尝试处理该异常的代码。

因此,由于未处理异常,线程将终止

天哪,我在 Swift 资源中找到了帮助。 Openstack Swift 使用来自 eventlet.

的绿色线程

它需要使用另一个已知的实现类

from eventlet import sleep
from eventlet.green import threading

而不是标准的 python 线程,因为它打了补丁,我怎么理解的。

所以这解释了为什么 Main 线程无处不在。