绿色线程等于“真实”线程吗?
我从理解eventlet.wsgi.server这篇文章中拿了一些示例代码。
from eventlet import wsgi
import eventlet
from eventlet.green import time
import threading
def hello_world(env, start_response):
print "got request", eventlet.greenthread.getcurrent(), threading.currentThread()
time.sleep(10)
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello, World!\n']
wsgi.server(eventlet.listen(('', 8090)), hello_world)
当我通过不同的客户端IP地址访问这个网络服务器时,我发现它们是并行处理的。而在hello_world
中的打印输出让我看到,它们是在两个不同的绿色线程中处理的,但却是在同一个操作系统线程里。
我刚接触Python,想知道每个绿色线程是不是都和一个底层的操作系统线程绑定在一起呢?
1 个回答
每个绿色线程(green thread)都和一个Python线程绑定,而这个Python线程又和一个操作系统线程(OS thread)绑定。理论上,Eventlet可以把绿色线程分配到多个Python线程上,进而分配到多个操作系统线程上,但这样做工作量很大,收益却很小,因为在CPython中,Python代码并不能并行执行。
简单来说,如果你想利用多个核心,最好换个语言,在Python中最好的办法是运行多个进程。快速的方法是使用multiprocessing
[2](从2.6版本开始就有),更稳妥的方法是手动使用os.fork
[3][4]。
稍微解释一下术语:对于大多数流行的操作系统,想要并行执行代码的唯一方法就是拥有多个操作系统线程。严格来说,你的请求并不是并行处理的,而是并发处理的;这正是因为只有一个操作系统线程。在任何时刻,只有一个绿色线程在执行某段代码。顺便提一下,普通的Python线程也是如此,这就是为什么Eventlet(或其他绿色线程库)大多数情况下可以直接替代使用,并且(大部分)不会引入新的奇怪的bug。
你可能会觉得这个答案有用: https://stackoverflow.com/posts/14227272/revisions
[1] http://wiki.python.org/moin/GlobalInterpreterLock
[2] http://docs.python.org/2/library/multiprocessing.html
[3] http://docs.python.org/2/library/os.html#os.fork
[4] https://github.com/jonashaag/bjoern/blob/master/tests/fork.py