Bor*_*kov 5 python django multithreading wsgi gil
假设我写了一个wsgi application.我上运行此应用程序Apache2的Linux多线程mod-wsgi配置,让我的应用程序在每一个进程的多个线程运行:
WSGIDaemonProcess mysite processes=3 threads=2 display-name=mod_wsgi
WSGIProcessGroup mysite
WSGIScriptAlias / /some/path/wsgi.py
Run Code Online (Sandbox Code Playgroud)
应用程序代码是:
def application(environ, start_response):
from foo import racer
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return [racer()] #call to racer creates a race condition?
Run Code Online (Sandbox Code Playgroud)
模块foo.py:
a = 1
def racer():
global a
a = a + 1
return str(a)
Run Code Online (Sandbox Code Playgroud)
我只是用变量创建了一个竞争条件a吗?我想,a是一个模块级变量,它存在于foo.py线程中并且是相同的(共享的)?
从中得出更多的理论问题:
a变量,所以我的例子不是线程安全的?Apache,Linux上我的应用程序的每个线程都是用C语言创建的pthreadsAPI和函数,pthread必须执行的是某种python解释器的主要功能?或者Apache是否以某种方式保护我免受此错误的影响?Tornado的HTTPServer?用python编写的Web服务器将线程实现为python级别的threading.Thread对象,并application在每个线程中运行函数.那么,我想这是一场竞争条件?(我也想,在这种情况下,我可以从底层C级抽象pthreads低于threading.Thread执行和只担心蟒蛇功能,因为解释不会让我修改C级共享数据并拧其运作.所以,唯一的办法打破线程安全对我来说是处理全局变量?是吗?)是的,那里有竞争条件,但它与进口无关。中的全局状态foo.a受到a + 1和之间的数据竞争a = ...;因为两个线程可以看到相同的值a,从而计算出相同的后继。
导入机制本身确实通过进程范围的锁来防止多个线程的重复导入(请参阅参考资料imp.lock_held())。虽然理论上这可能会导致死锁,但这几乎不会发生,因为很少有 python 模块会在导入时锁定其他资源。
sys.path这也表明随意修改可能是安全的;因为这通常只发生在导入时(为了额外导入的目的),并且该线程已经持有导入锁,所以其他线程不能导致也会修改该状态的导入。
不过,修复比赛racer()非常容易:
import threading
a = 1
a_lock = threading.Lock()
def racer():
global a
with a_lock:
my_a = a = a + 1
return str(my_a)
Run Code Online (Sandbox Code Playgroud)
您控制的任何全局可变状态都需要它。
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |