V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
nilai
V2EX  ›  Python

tornado 中的阻塞求指教

  •  
  •   nilai · 2014-03-30 19:49:49 +08:00 · 5277 次点击
    这是一个创建于 3885 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如下代码:
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import time
    import os

    from tornado.options import define, options
    define("port", default=8000, help="run on the given port", type=int)

    class IndexHandler(tornado.web.RequestHandler):
    def get(self):
    print "begin"
    #time.sleep(10)
    os.system("ping www.baidu.com -c 10")

    if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/sleep", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()




    现在当浏览器请求地址:
    http://127.0.0.1:8000/sleep 会一直ping 10次百度,此时有另一个用户也访问这个地址, 但是另一个用户会被阻塞掉,一直等到第一个用户ping执行完后 第二个用户才能执行, 怎么样实现非阻塞的操作.
    27 条回复    1970-01-01 08:00:00 +08:00
    ponyfk
        1
    ponyfk  
       2014-03-30 20:37:00 +08:00
    看这个, 结合 subprocess
    http://tornadogists.org/489093/
    但是不推荐
    zenliver
        2
    zenliver  
       2014-03-30 20:50:36 +08:00
    开个进程池,仍进去
    openroc
        4
    openroc  
       2014-03-30 22:19:04 +08:00
    @nilai, search tornado.concurrent.run_on_executor
    zenliver
        5
    zenliver  
       2014-03-30 22:46:17 +08:00
    @yakiang 曼城,,,
    pythonee
        6
    pythonee  
       2014-03-30 22:53:21 +08:00
    啊,tornado处理请求不是多线程的吗?不是tornado用户,请别喷
    yakiang
        7
    yakiang  
       2014-03-30 22:57:02 +08:00
    @zenliver 蓝粉 ^ ^ 这是我多个社交帐号的头像
    nilai
        8
    nilai  
    OP
       2014-03-30 23:01:30 +08:00
    Twisted 呢,能实现这个功能么?
    wangfengmadking
        9
    wangfengmadking  
       2014-03-30 23:21:08 +08:00
    加异步 coroutine
    zenliver
        10
    zenliver  
       2014-03-31 00:56:15 +08:00
    @wangfengmadking 线程都阻塞了,加异步没作用的, 本来tornado就不适合cpu bound的应用
    ivanlw
        11
    ivanlw  
       2014-03-31 08:36:08 +08:00 via iPhone
    @zenliver 什么叫CPU bound呢
    nilai
        12
    nilai  
    OP
       2014-03-31 09:35:55 +08:00
    @zenliver 那是不是python就干不了这事了?
    zenliver
        13
    zenliver  
       2014-03-31 09:56:36 +08:00
    @ivanlw cpu密集型
    CMGS
        14
    CMGS  
       2014-03-31 10:09:43 +08:00
    等等,CPU密集?
    time.sleep也好,os.system这种也好,前者直接 yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 10)这样加入事件循环,后者异步subprocess,tornado里面有tornado.process。

    你是一个大业务循环一百亿次那才叫CPU密集,这只能算IO阻塞,但问题是这样的业务对于单进程单线程的事件驱动模型来说根本就是无解。要解决这种事无外乎就是stackless,线程池这种了,对于传统的CPython而言,只能用进程来解决。
    kingxsp
        15
    kingxsp  
       2014-03-31 11:58:47 +08:00   ❤️ 1
    查看这里: https://gist.github.com/kingxsp/9884962 应该是个可用的改写。
    nilai
        16
    nilai  
    OP
       2014-03-31 14:37:25 +08:00
    @kingxsp python2.7下没有 tornado.concurrent
    kingxsp
        17
    kingxsp  
       2014-03-31 15:10:39 +08:00
    这个并发库在python3自带在python2需要安装sudo pip install futures 即可使用
    kingxsp
        18
    kingxsp  
       2014-03-31 15:12:14 +08:00
    tornado.concurrent 是有的啊。我就是在python2.7下进行的,到是 futures 是 python3 下默认带的。
    nilai
        19
    nilai  
    OP
       2014-03-31 16:01:45 +08:00
    @kingxsp


    root@xxxx-All-Series:~# ipython
    Python 2.7.3 (default, Feb 27 2014, 19:58:35)
    Type "copyright", "credits" or "license" for more information.

    IPython 0.12.1 -- An enhanced Interactive Python.
    ? -> Introduction and overview of IPython's features.
    %quickref -> Quick reference.
    help -> Python's own help system.
    object? -> Details about 'object', use 'object??' for extra details.

    In [1]: import tornado.concurrent
    ---------------------------------------------------------------------------
    ImportError Traceback (most recent call last)
    /home/yzy/<ipython-input-1-6952f9510533> in <module>()
    ----> 1 import tornado.concurrent

    ImportError: No module named concurrent
    nilai
        20
    nilai  
    OP
       2014-03-31 16:18:11 +08:00
    @kingxsp 问题解决了. 是因为tornado 用的apt-get安装的.后来下源码安装就没问题. thanks
    ggarlic
        21
    ggarlic  
       2014-03-31 23:01:57 +08:00
    @nilai very easy
    使用ProcessProtocol
    https://twistedmatrix.com/documents/13.0.0/core/howto/process.html

    之前看到有人用twisted写爬虫用urlopen嫌慢,其实twisted也有异步的urlopen版本twisted.web.client.getPage

    写异步用同步的time.sleep之类的不是自己给自己找麻烦么
    zenliver
        22
    zenliver  
       2014-03-31 23:31:31 +08:00
    @ggarlic 顶, 呵呵,,,
    zenliver
        23
    zenliver  
       2014-03-31 23:34:14 +08:00
    @CMGS 分析的很好, 不过time.sleep不就相当于一个cpu密集型的operation吗
    CMGS
        24
    CMGS  
       2014-04-01 01:01:23 +08:00
    @zenliver time.sleep 其实比较特殊,为什么说特殊呢,原本是用来模拟大循环(业务向)的CPU密集操作,但是在event-driven的驱动里面,比喻起来应该是suspend,和时间循环是相关的
    nilai
        25
    nilai  
    OP
       2014-04-01 16:01:44 +08:00
    @ggarlic
    能不能像 kingxsp 来个可用的改写
    ggarlic
        26
    ggarlic  
       2014-04-01 22:17:24 +08:00
    <script src="https://gist.github.com/ggarlic/f0d5c4135a98cce96c7a.js"></script>
    在我这测试能用,请自行修改ping的路径。
    然后,web开发我不熟,我拿twisted都是写别的东西。用同一个浏览器同时打开几个页面还是会顺序访问,用不同浏览器,或者直接终端里同时跑几个curl就没事。Twisted Network Programming Essentials, 2nd EditionEssential Twisted里关于这个的说明:
    If you run Example 4-10 and then load multiple instances of http://localhost:8000 in a browser, you may still find that the requests are processed serially. This is not Twisted’s fault: some browsers, notably Chrome, serialize requests to the same resource. You can verify that the web server isn’t blocking by issuing several simultaneous requests through cURL or a quick Python script.
    ggarlic
        27
    ggarlic  
       2014-04-01 22:21:48 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4116 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 10:18 · PVG 18:18 · LAX 02:18 · JFK 05:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.