【发布时间】:2017-07-12 20:10:50
【问题描述】:
在 CPython 环境中,一个线程不会从另一个线程获取 GIL,除非它被阻塞(比如使用 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')
#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()
问题:
一个线程什么时候有机会从另一个线程获取 GIL 来服务客户端?是conn.recv(16),允许服务器运行多线程吗?
【问题讨论】:
-
“在 CPython 环境中,一个线程不会从另一个线程获取 GIL,除非它被阻塞(比如使用睡眠)或在 IO 上” - 是什么让你这么认为?
-
等待网络,这是此类服务器通常所做的大部分工作,正在在 IO 上被阻止。
-
@user2357112 示例 1: this 程序在没有
sleep()的情况下作为顺序代码工作。end-start输出告诉 示例 2: 以上代码在查询中,线程 1 在recv()上释放 GIL。这让我觉得 -
打印的
end-start值并不意味着程序是按顺序执行的,当然也不意味着 GIL 释放仅在线程被阻塞或执行 I/O 时发生。 -
@user2357112
t1CPU 绑定线程占用提供的 CPU 时间片并且永远不会放弃 GIL,直到它完成,或者直到没有操作码完成执行。然后t2占用提供的 CPU 时间片。主线程无论如何都被阻塞了。这就是我所说的顺序
标签: python multithreading gil