为什么gunicorn使用相同的线程

问题描述 投票:0回答:2

一个简单的Python名称myapp.py:


import threading
import os

def app(environ, start_response):
    tid = threading.get_ident()
    pid = os.getpid()
    ppid = os.getppid()
    
    # #####
    print('tid ================ ', tid) # why same tid?
    # #####
    print('pid', pid) # 
    print('ppid', ppid) # 

    data = b"Hello, World!\n"
    start_response("200 OK", [
        ("Content-Type", "text/plain"),
        ("Content-Length", str(len(data)))
    ])
    return iter([data])

我从gunicorn开始: Gunicorn -w 4 myapp:app

[2022-03-28 21:59:57 +0800] [55107] [INFO] Starting gunicorn 20.1.0
[2022-03-28 21:59:57 +0800] [55107] [INFO] Listening at: http://127.0.0.1:8000 (55107)
[2022-03-28 21:59:57 +0800] [55107] [INFO] Using worker: sync
[2022-03-28 21:59:57 +0800] [55110] [INFO] Booting worker with pid: 55110
[2022-03-28 21:59:57 +0800] [55111] [INFO] Booting worker with pid: 55111
[2022-03-28 21:59:57 +0800] [55112] [INFO] Booting worker with pid: 55112
[2022-03-28 21:59:57 +0800] [55113] [INFO] Booting worker with pid: 55113

然后我curl http://127.0.0.1:8000/(或使用浏览器)。日志如下:

tid ================  4455738816
pid 55112
ppid 55107
tid ================  4455738816
pid 55111
ppid 55107
tid ================  4455738816
pid 55113
ppid 55107

问题是为什么tid相同但pid不一样

ps:代码来自https://gunicorn.org/主页。

python multithreading gunicorn
2个回答
2
投票

Gunicorn 创建多个进程来避免 Python GIL。每个进程都有一个唯一的PID。


关于线程,

threading.get_ident()
是Python特定的线程标识符,它应该被视为无意义并且仅在本地进程内相关。

相反,您应该使用

threading.get_native_id()
,它返回唯一的系统范围线程标识符。

请记住,后者可能会在线程关闭时被回收和重用。


0
投票

Gunicorn 在使用

gevent
工作类型运行时可能会使用单个操作系统线程。当使用
gevent
时,我观察到新线程是“假的”,而不是全部指向相同的
native_id
gevent
库,通过
greenlet
,似乎做了一堆猴子补丁,改变了
threading
等库的行为。这可能会导致问题,例如使用
asyncio
+
threading
将会被破坏。

您可以切换到不同的工作线程以确保使用单独的操作系统线程,例如

sync
工人阶级。

© www.soinside.com 2019 - 2024. All rights reserved.