线程阻塞主线程
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
线程无处不在。
我不是 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
线程无处不在。