【发布时间】:2022-01-14 16:18:18
【问题描述】:
假设:
线程....start() 阻塞,直到启动完成。
题:
假设是对还是错?
Start http web server then open browser 有以下代码。
import sys
import time
import threading
import webbrowser
from http.server import HTTPServer, SimpleHTTPRequestHandler
ip = "127.0.0.1"
port = 3600
url = f"http://{ip}:{port}"
def start_server():
server_address = (ip, port)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
httpd.serve_forever()
threading.Thread(target=start_server).start()
webbrowser.open_new(url)
while True: # make a blocker to prevent the application finish of execute:
try:
time.sleep(1)
except KeyboardInterrupt:
sys.exit(0)
这很好用。但是,以下方法也有效。
import sys
import time
import threading
import webbrowser
from http.server import HTTPServer, SimpleHTTPRequestHandler
ip = "127.0.0.1"
port = 3600
url = f"http://{ip}:{port}"
def start_server():
server_address = (ip, port)
httpd = HTTPServer(server_address, SimpleHTTPRequestHandler)
httpd.serve_forever()
threading.Thread(target=start_server).start()
webbrowser.open_new(url)
假设:
thread....start() 实际上会阻塞,直到 start 完成。因此,webbrowser.open_new(url) 在启动完成之前不会执行。从而使以下内容变得不必要。
while True: # make a blocker to prevent the application finish of execute:
try:
time.sleep(1)
except KeyboardInterrupt:
sys.exit(0)
经过大量搜索,我无法证明或反驳假设。
【问题讨论】:
-
请记住,因为如果使用 Python GIL(全局解释器锁),一次只有一个线程可以执行 Python 代码。当您的线程启动时,它会占用 CPU,直到线程阻塞 I/O 或输入一些非 Python 代码,然后主线程才能继续。无法保证这一点,但它就是这样工作的。
-
是的,就像 Tim 说的,Python 是单线程的;如果您想要真正的并行性,则必须使用多处理。
-
@TimRoberts 尽管由于 GIL,一次只执行一个线程,Python 运行时可以(并且将)更改正在运行的线程,独立于 I/O 阻塞或运行非 Python 代码:线程-change 可以发生在 Python VM 上的任何字节码指令边界。正如您所描述的那样,为您提供确定性和用户可控的上下文切换的是基于异步的代码。
-
伙计们:像这样的 HTTP 服务器在 Python 中使用多线程非常好:等待 http 连接到达是 I/O 阻塞,而其他线程只是以透明的方式运行。跨度>
标签: python multithreading