Python 半同步半异步的疑问?

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

通过管道的方式能传递连接吗这个还真太清楚。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/561806

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX