GIL 如何与多线程服务器配合使用?

ove*_*nge -1 python multithreading gil

在 CPython 环境中,一个线程不会从另一个线程获取 GIL,除非它被阻塞(比如 using sleep())或在 IO 上

在下面的服务器代码中,

# server.py
import socket
import sys
from threading import Thread

def echoHandler(conn, addr):
    try:
        while True:
            data = conn.recv(16) # Blocking call
            if data:
                print(data.decode('utf-8'))
                conn.sendall(data)
            else:
                break
    finally:
        print('Closing the connection from server')
        conn.close()

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = ('localhost', 10006)
    sock.bind(server_address)
    sock.listen(1)
    while True:
        conn, addr = sock.accept()
        t = Thread(target=echoHandler, args=(conn, addr))
        t.daemon = True
        t. start()
        print('Waiting for another conn')
Run Code Online (Sandbox Code Playgroud)
#client.py
import socket
import pdb

# pdb.set_trace()
if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = ('localhost', 10006)
    print('connecting to', server_address)
    sock.connect(server_address)

    while True:
        try:
            message = input().encode('utf-8')
        except EOFError:  #EAFP
            print('Breaking ')
            break
        sock.sendall(message)
        data = sock.recv(16) # Blocking call
        print(data.decode('utf-8'))
    print('close the socket')
    sock.close()
Run Code Online (Sandbox Code Playgroud)

题:

一个线程什么时候有机会从另一个线程获取 GIL 来服务客户端?是否conn.recv(16)允许服务器多线程运行?

Cha*_*ffy 5

是的,GIL 不会在conn.recv(16)(毕竟是网络 I/O)期间保留。

它还定期发布(2010 年之前,每 100 个操作码;最近,以可配置的 5 毫秒间隔)以避免线程饥饿。