Python 板


LINE

最近在做一个专案,里面有三十个设备要控制 因为三十个设备不能互相卡住,所以就开了三十个 thread 另外程式要有所展示,所以 main thread 也就是 ui thread 由 main thread 开出 30 个设备 thread, 那现在看到有 31 个了 CPU 的效率拨进来这支程式,假设是平均且 free run 那麽每个 thread 都占用了 1/31 的 CPU 时间 我在每个 thread 做过一次判断後,都有 sleep(1) 这意思是每个设备,每秒都判断一次应该要做什麽动作 这时 UI 变很卡了... 理想上每个 thread 遇到 sleep 指令,它就睡了 然後 CPU 时间会拨给剩下的 thread 去平均分享 如果每个设备的判断式都执行很快,那麽在别的 thread 的 sleep 一秒内,就足以做完 当程式跑久以後,每个 thread 都有可能全速奔驰 只要它们别同时醒着 也许是我写的判断式效率不好,渐渐的感觉到程式变很卡 而把 sleep 加长有助於解决这个问题 其实我想分配每个 thread 的优先权了 一开始的想法便是利用 lock 首先产生一个 lock 当全域物件 30 个 thread 都引用它且互斥 with lock: 设备判断式 这样可使 30 个 thread 同时只能有一个执行 而我在设备判断式里,也只简单的把一个计数器加一 据以观察 30 个设备的执行机率平不平均 结果是非常不平均;但这样写是最简单的 我会担心,会不会运气不好,某设备经常不执行? 後来我想了一个法子,由我自己控制 我产生一个 list, 里面有所有 30 个设备 thread 的指标 只要某 thread 被执行,就把它移到 list 的最尾端 那麽最前端就是没被执行到,我希望它执行的 用这个方法等於把 30 个 thread 串起来,因为同时只有一个在动 我等於就把它们变一个 thread (难道 thread group 就是在做这件事?) 我希望的是 30个设备 thread 总共占用 50% CPU 时间 而 main thread 占用另外的 50% CPU 时间;也就是平分~ 这样会不会有什麽问题呢?有没有更简单的想法呢? 觉得自己打造了不少轮子 而且这样似乎又违反了一开始的初衷(设备不要互相卡住) 因为我只要一个设备有 bug, 卡住不动 剩下 29 个设备会全部赔葬 XD 把话反过来说好了,一开始我就不想写 30 个 thread,我本来要用一个 thread 做完 举例来说,一个射击类电玩里,敌机可能有一百架 难道这电玩就用一百个 thread 来写? 当然是一个 thread 就很好写啊... 但因为我的开发出了点问题,老板就叫我快点改成 multi-thread 至少一个设备卡住也不影响其他设备 另外当初在学同步物件时,有个东西就搞不懂 好像有个叫 信号机 的物件,它不像 lock 是完全互斥 而是它可以允许一个量(比如同时有五个 thread pass,一个结束才能再唤醒一个) 我一直无法想像这东西用在哪,从没用过 难道就用在这? 比如,我 30 个设备会卡,但当初开发到一半时还很顺,大概可以容许 15 个设备 我就设 15 个设备的信号机,这样程式也不会卡,但也不是同时所有 thread 都在动 难道就是用在这? 但我还是会担心,允许 15 个设备,就有哪个设备不受照顾,睡死一方.. 这种同步物件,有保证所有 thread 的机率尽量均等吗? 以上请教,谢谢 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 49.216.44.32 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1674995478.A.744.html 另一个想法,这搞不好是 GIL 的锅 不如把 30 个 thread 拆成 30 个 process 还是会很快 UI 则独立出来另一支程式 不过这样我一直没去想 thread safe 的问题,现在就要好好想想了 (我每个设备都要去碰 RS-232, i2c 等等硬体,这下硬体大车拼了) 但暂时不想这样玩 不然万一真的玩光了 CPU 效率,不就影响到 OS 了... ※ 编辑: HuangJC (49.216.44.32 台湾), 01/29/2023 20:43:07 想想虽然有 GIL,但 multi-thread 还是有用处 因为我有控制速度慢的硬体 全部三十个设备的 relay 都在 RS-232 上(其实是 485,全部连上再用modbus 定址) 当一道硬体指令发出且还没回应时,CPU 时间就拨给其他 thread 了 我没记错吧? 所以如果我不用 multi-thread 写,那麽这些零散时间就不会被利用到 当控制硬体时,因为一个设备它的 thread 仍在占用,且我叫它们全互斥 那其实程式会跑很慢!
1F:→ surimodo: 叫老板升级CPU 01/29 23:13
这太暴力了 XD,整个专案成本都会上升 目前用 RPI 3B+
2F:推 poototo: GIL下,thread本来就是互斥的 01/29 23:18
3F:→ poototo: 客制互斥锁没有改变thread互斥性,只会影响公平性 01/29 23:19
因为我也只抱怨公平性 XD,但我发现做不来 比如 thread 1, 然後 thread 2, 然後 thead 3 ; 这是我手工打造的顺序且全速执行 如果 thread 1 里有个 sleep 我得自己去改写, 因为这时它会空等,没让 thread 2 趁机先跑 sleep 是我自己下的,全域搜寻并改写不难 但如果是操作低速硬体,这时多出来的 CPU 效率可以给 thread 2 先跑 这我改写不出来;因此我有在想同时允许两个 thread 跑
4F:→ poototo: 可试试Coroutines&Tasks,管理成本比thread低很多 01/29 23:19
协同式多工?我想到很久前写 windows 的 message loop 的经验 我好像就正在手工打造 coroutines,得比比官方的轮子怎麽用
5F:→ TakiDog: 当今天出现sleep 应该要思考流程设计 01/30 01:49
6F:→ TakiDog: asyncio.sleep 会更好的去释放资源 01/30 01:52
7F:→ TakiDog: 你大可一个设备一个process沟通,资料再汇整到一处 01/30 01:53
https://ithelp.ithome.com.tw/articles/10262385 看了这个才理解大家说的 task 刚还去 google task vs process, 因为我搞混了两个词 看来一个可执行档跑起来,叫做 process 而一个可被执行的程式片段,叫做 task
8F:推 timsheu: asyncio效能比multi-thread好很多,但语法要熟悉一下 01/30 09:29
9F:→ timsheu: multi-process的话,若资料要互通要用share memory 01/30 09:30
10F:→ timsheu: 官方的asyncio用不习惯的话,也可以用trio,比较容易上手 01/30 09:32
11F:→ timsheu: asyncio要注意一下python版本,有些语法只适用python3.8+ 01/30 09:34
12F:→ timsheu: 我是用rpi4b架fastapi,python3.7,asyncio+rxpy 01/30 09:35
13F:推 timsheu: asyncio要同时跑coroutine的话,要包成task才行。 01/30 09:40
14F:→ day831231: 假设只有一个CPU 01/31 06:32
15F:→ day831231: 那用thread 跟 process 速度不会差到太多 01/31 06:32
16F:→ day831231: 感觉只是使用方式错误 01/31 06:32
在 C 是这样,在 python 因为有 GIL,它的 thread 是阉割的... 我曾想 GIL 是不是一种设计上的限制, 後来发现它很大量的减少我使用 critical section,也算方便 举例来说,一个变数如果略大,占 8 个 byte 好了 真正的 multithread 我必需担心当变数只更新了 4 个 byte 就被另一个 thread 参考 解决方法就是用各种同步物件去限制 但在 GIL 的阉割之下,这种事在 python 我从不担心 CPU 当然不会更有效率,举两个 thread 来说,c 和 python 都是'大家平分各50%效率' 差别就在'卡卡的',比如,同时控制 x, y 轴的控制器,若 x, y 轴各用一个 thread 用 C 写,就能完美的走斜线,用 python 写,看网友抱怨是会抖动 现在 Coroutine, 译为协程,看到今天感觉这东西更妙 颇有以前我写 windows sdk 时接触的 message loop 的感觉(事实上它生了个 loop) 我可以指定在 sleep 时才切换 cpu 到另一个 'thread' 切换时机由我指定,那我就更不担心变数被另一个 thread 偷换掉了 我对同步的协调应该可以更少 但同样的,一个 'thread' 卡住,就是大家都卡住,这问题又冒出来了 XD ※ 编辑: HuangJC (49.216.44.32 台湾), 01/31/2023 06:51:57 为什麽 Coroutine 比 Multithread 有效率?我有个猜想,但不知有没有人附议 (没法子,我经常要去想原理,以便应用在其他地方,或用来理解 bug) MT 需要本文切换,这是它慢的原因 而它何时切换?因为 GIL,它不会在指令执行到一半时切换。它总是执行完。 上次看到某网页写,它总是执行一百道 python 指令,然後切换 100 是写在 spec 里的或者任何一家实作 python 的厂商都可以改?我不知道 但反正它是这样切 而 C 语言的切换是用时间,比如 100 毫秒,由 timer 发起中断,CPU 收到中断 配合 OS 写好的中断处理常式引起本文切换。因为是用时间,所以平滑多了 而一道 C 指令会译成几道组合语言?不清楚。每个机械码占用几个机械周期?不清楚 但用 timer 由外部引起中断,这平滑很多很多 平滑到 C 指令可能才执行一半,就被切去另一个 thread 了 Coroutine 则是本文切换由软体工程师决定,在每个 sleep 点才切换 如果完全不写 sleep,就会完全不切换;引起 Block XDDD 而因为切换点都在 python 肚子里,所以也不劳动外部 timer,不劳动 OS 中断常式 因此才能做到 Coroutine 的 'thread' 不必注册到 OS 层级 注册到哪级是一回事,我以为只要本文切换就是个负担 但现在这个本文都是 python 肚子里的事,可能会因此小点 猜是这样猜啦... ※ 编辑: HuangJC (49.216.44.32 台湾), 01/31/2023 07:57:50
17F:推 Falldog: GIL卡的是python layer, C level的不会卡, eg. socket io 01/31 23:19
18F:→ Falldog: 理论上ui会感到卡一定是main thread做太多事卡住render 01/31 23:19
19F:→ Falldog: 用thread的话,就尽量用event queue的方式沟通 01/31 23:21
20F:→ Falldog: 如果在main thread需要跟其他thread用lock抢资源的话 01/31 23:22
21F:→ Falldog: 会卡似乎也是预期内的事 01/31 23:22
22F:→ Falldog: 补充一下 GIL, C level 有机会可以 release GIL 02/01 00:44
有空我检查一下,我不记得我 main thread 有用 lock 应该只是 31 个 thread 真的太多,拖慢了 如果用了 coroutine, 那真是把 30 个变成 task,共享一个 thread 我目前做法是观察会变卡的东西,最明显的就是 mainthread 每秒更新的时钟(hh:mm:ss) 它变成两秒跳一次,於是我把何时更新其值,设一个 watch dog 如果其值用跳的,我就开动 lock 这个 lock 就是用来锁住 30 个设备的 thread 但目前这样做也不会顺就是了
23F:推 poototo: PEP 703就有可能让GIL Optional 02/01 00:52
※ 编辑: HuangJC (49.217.70.24 台湾), 02/01/2023 09:10:48 各位太热情了,目前我着迷在 Coroutine 了 我相信它可以解决我的问题。。。 学每个东西都需要时间,我要先决策要不要去学,然後才学 而不是学了才来决策。。。。 (我怎麽闻到自己不求上进的 fu) 不是啦,我不只是工程师,我也要想自己的成本问题啊 当我能力不足,先决策再投资生命并没有错! 我会先 google 一下大家提的东西,但我未必学得会,未必投资;对吧 :P
24F:→ zerof: 左转 pypy 02/01 16:38
25F:→ s9041200: 试过epoll吗? 02/01 20:10
※ 编辑: HuangJC (123.204.157.162 台湾), 02/03/2023 12:47:28
26F:推 eight0: https://github.com/eight04/pyWorker 不知道有没有帮助 02/04 00:17
27F:→ gomi: cpu bound 即使异步也没用吧 我想 09/09 20:43







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP