python + wsgi上多

假设我写了一个wsgi application 。 我在Linux使用多线程mod-wsgi配置在Apache2上运行此应用程序,以便我的应用程序在每个进程的多个线程中运行:

WSGIDaemonProcess mysite processes=3 threads=2 display-name=mod_wsgi
WSGIProcessGroup mysite
WSGIScriptAlias / /some/path/wsgi.py

应用程序代码是:

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?

模块foo.py:

a = 1
def racer():
    global a
    a = a + 1
    return str(a)

我是否创建了变量a的竞争条件? 我猜, a是一个模块级别的变量,存在于foo.py并且在线程之间是相同的(共享)?

更多的理论问题来源于此:

  • 同一进程中的并发线程访问和修改相同a变量,所以我的例子不是线程安全的?
  • 如果我的网络服务器是Apache ,我的Linux应用程序的每个线程都是在C层上用pthreads API和函数创建的, pthread必须执行的函数是某种python解释器的主函数? 或者Apache保护我不知何故从这个错误?
  • 如果我是在像TornadoHTTPServer这样的python写的网络服务器上运行它,该怎么办? 用python编写的Web服务器将线程实现为python级别的threading.Thread对象,并在每个线程中运行application函数。 那么,我认为这是一个竞争条件? (我也假设,在这种情况下,我可以从threading.Thread实现中抽象出底层的C层pthreads ,并且只考虑python函数,因为解释器不会允许我修改C层共享数据并解决它的功能。解决线程安全问题的唯一方法是处理全局变量?是吗?)

  • 是的,你在那里有一个竞赛条件,但它与进口无关。 foo.a的全局状态受到a + 1a = ...之间a + 1数据竞争; 因为两个线程可以看到相同的值a ,并由此计算出相同的继任者。

    导入机制本身通过一个进程锁来防止多线程重复导入(参见imp.lock_held() )。 尽管理论上这可能导致死锁,但几乎从不会发生这种情况,因为很少有python模块在导入时锁定其他资源。

    这也表明,可以sys.path修改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)
    

    这将是您控制中的任何全局,可变状态所需要的。


    阅读关于各种进程/线程配置的mod_wsgi文档,特别是关于数据共享的内容。

  • http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading#Building_A_Portable_Application
  • 特别是它说:

    在仍然使用子进程本地模块中的全局数据(例如作为缓存)的情况下,全局数据的访问和修改必须由本地线程锁定机制来保护。

    链接地址: http://www.djcxy.com/p/86485.html

    上一篇: python + wsgi on a multi

    下一篇: How exactly is Python Bytecode Run in CPython?