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
fghjghf
V2EX  ›  Python

Python 半同步半异步的疑问?

  •  
  •   fghjghf · 2019-05-07 14:33:35 +08:00 · 2044 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。
    主进程通过 epoll 循环监听 socket,有新连接就分出去同步进程。进程数是根据 CPU 核心数创建的,毕竟创建多了 CPU 切换、创建销毁等影响性能。我尝试过多种方式,fork,进程池,等都不行。
    请问有大佬遇到过吗?能贴下实现代码吗
    13 条回复    2019-05-08 16:50:36 +08:00
    ebingtel
        1
    ebingtel  
       2019-05-07 16:24:33 +08:00
    没看明白,是“不行”在哪里?
    fghjghf
        2
    fghjghf  
    OP
       2019-05-07 16:27:42 +08:00
    @ebingtel 进程数和 CPU 数不同步,我现在的做法有两种 1、无限 fork,2、用进程池
    diveIntoWork
        3
    diveIntoWork  
       2019-05-07 16:37:09 +08:00
    有点莫名其妙的,首先 epoll 不是应该用线程吗,除非你有隔离资源的需求;其次,进程数也不用和 CPU 数同步吧,现在 CPU 都是时钟分片,进程和线程比 CPU 数量多才能保持高 CPU 利用率
    xfriday
        4
    xfriday  
       2019-05-07 20:33:02 +08:00
    @diveIntoWork Py 有 GIL,楼主如果用进程池的话,任务如何调度、中断、恢复呢?总不可能做成任务队列吧?那样如果有长时间占用 CPU 资源的任务,后面的任务就等着排队了,要么就是做成 Go 那样的 Goroutine
    ipwx
        5
    ipwx  
       2019-05-07 20:41:43 +08:00
    @xfriday 队列是可以用 asyncio 来处理的。。。我相信 epoll 也有方案,只不过我没用过。
    BiggerLonger
        6
    BiggerLonger  
       2019-05-07 22:11:28 +08:00
    看看 gunicorn 的代码, 或许有用
    wwqgtxx
        7
    wwqgtxx  
       2019-05-08 08:50:33 +08:00
    @xfriday 无论是 PY2 还是 PY3 只要尝试长时间占用 CPU 资源就一定会被解析器强行剥夺,释放 GIL 让其他线程运行,我记得 PY2 是按照虚拟机指令条数,PY3 是按照时间片,不可能存在“有长时间占用 CPU 资源的任务,后面的任务就等着排队了”的情况
    www5070504
        8
    www5070504  
       2019-05-08 09:11:59 +08:00
    没看懂说的 新的连接 fork 和 进程数是根据 cpu 数量创建的 这两句矛盾了啊 意思是上限等于 cpu 数量么 用 select 肯定可以的 epoll 没试过 感觉 epoll 和创建进程不搭。。
    xfriday
        9
    xfriday  
       2019-05-08 11:34:17 +08:00
    @wwqgtxx 我说的是楼主如果用进程池做的话,进程数:任务数= M:N,你说的是使用线程,并且线程数:任务数 = 1:1
    xfriday
        10
    xfriday  
       2019-05-08 11:34:56 +08:00
    每个进程都有独立的 GIL 锁
    fghjghf
        11
    fghjghf  
    OP
       2019-05-08 15:45:15 +08:00
    @diveIntoWork 线程有 GIL 锁,所以才不考虑的。和 CPU 核心数同步,是为了减少切换和创建销毁造成的开销。最好是能绑定 CPU 核心。
    fghjghf
        12
    fghjghf  
    OP
       2019-05-08 16:20:01 +08:00
    @www5070504 是这样的:主进程不断循环用 epoll 监听 socket,有新链接,就分出去工作进程去非堵塞执行逻辑,写入写出等,遇到 eagain 就通过管道传给主进程再次循环。我是用 psutil 获取 CPU 核心,期望的效果是:创建 CPU 核心数*2 的进程。例如 epollin,epollout 事件触发后,马上放进 work 进程。一来减少切换和创建销毁的开销,二来兼顾 IO 等待时避免 CPU 空转。现在就卡在如何创建和复用有限进程
    www5070504
        13
    www5070504  
       2019-05-08 16:50:36 +08:00
    @fghjghf 跨进程访问好像很费劲 我记得 multiprocessing 提供了一个代理用来访问其他进程的对象 不知道对你有用不

    通过管道的方式能传递连接吗这个还真太清楚。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5885 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 02:06 · PVG 10:06 · LAX 18:06 · JFK 21:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.