子虚乌有 发表于 2022-12-4 23:18

python代码多线/进程性能问题

本帖最后由 子虚乌有 于 2022-12-4 23:19 编辑

挺简单一段代码。不过又是多线程,又是多进程

def updateResultDict(key, result,lockCaculator,caculateResult):
        lock.acquire()
        lockCaculator.acquire()       
        caculateResult = (datetime.datetime.now(), list(map(lambda x: x, result)))       
        lockCaculator.release()
        lock.release()


本身这个方法实际逻辑就一句话:把计算结果放到一个普通dict里。
但是result是有几十个线程,每个线程都会生产出一个result,根据key来更新。所以会有多线程访问这个caculateResult。然后要有线程锁lock
caculateResult又作为计算结果会被其它进程访问,又有进程锁lockCaculator
现在问题出在lock.acquire()上,很慢。要4秒。
整个程序只有这个地方用到这个线程锁,进程锁在另外一个读结果的客户端用到,实际上目前没有enable所以可以认为其它地方也没用到。
而caculateResult = (datetime.datetime.now(), list(map(lambda x: x, result)))        只是个dict的upda特。用时几乎可以忽略。
所以这个4秒很奇怪

子虚乌有 发表于 2022-12-4 23:22

或者说是不是我开了进程锁,就不需要线程锁了。
不知道python是个什么机制。

chenwanqq 发表于 2022-12-5 02:08

一你这个map要花多长时间啊,第二你考虑考虑一定要这么写么,已知字典本身的单个操作算是线程安全的吧

chenwanqq 发表于 2022-12-5 02:09

那么你这么一长串的句子里哪些是一定要加锁的,哪些不用加锁得想清楚

chenwanqq 发表于 2022-12-5 02:10

至于python本身的机制,你应该也知道有GIL,对cpu密集型的程序来说多线程没有意义,当然io密集型除外

子虚乌有 发表于 2022-12-5 06:59

chenwanqq 发表于 2022-12-5 02:09
那么你这么一长串的句子里哪些是一定要加锁的,哪些不用加锁得想清楚

caculateResult = xxx
需要锁,caculateResult本身是被多个线程共享的。
这个操作一瞬间。
后面那个map也是一瞬间,因为list很小,里面是浮点数,数量才不到100。

子虚乌有 发表于 2022-12-5 07:00

我每一行都打印时间了,大头都是第一句
“         lock.acquire()”

jctc 发表于 2022-12-5 07:07

lvcha 发表于 2022-12-5 08:22

jctc 发表于 2022-12-5 08:41

風舞雪 发表于 2022-12-5 12:17

python线程推荐写在一个class里 把线程锁也设置成instance variable就好
然后用就 with self.lock 去更新另外一个instance variable

kwg 发表于 2022-12-5 12:42

我说下我的直觉体会
算你8进程50线程,那一共是400次调用,4000ms/400 = 10ms,也就是平均这套操作下来需要耗时10毫秒,那可不得卡在lock acquire上面么

jjy376195855 发表于 2022-12-5 15:14

jjy376195855 发表于 2022-12-5 15:18

子虚乌有 发表于 2022-12-5 15:55

jjy376195855 发表于 2022-12-5 15:18
为啥要上两道锁????太迷幻了,你是在作课设么

实际上现实中的多线程多进程的第一步就是识别那些东西需 ...

不算吧。
因为这个caculateResult这个dict事实上就是既被多线程往里放数据,又被多进程读数据。
lock是线程锁
lockCaculator是进程锁

子虚乌有 发表于 2022-12-5 15:56

jjy376195855 发表于 2022-12-5 15:14
你为啥要这么写这个东西,我没搞懂真的

顺序执行会慢么?

你这个倒是提醒我了,真的没试过顺序执行。我有时间试试看。

d2loader 发表于 2022-12-6 02:05

概念都很模糊的时候就别上多线程了

看你代码写的是计算,尽可能想办法用numpy去凑

比你写的这种可能快100倍



—— 来自 Xiaomi Mi 10, Android 12上的 S1Next-鹅版 v2.5.4

ghgfj 发表于 2022-12-6 12:13

小野賢章 发表于 2022-12-6 12:51

如果 result 是一个内部类型,其实不用加线程锁。
python 因为有 GIL,单个进程只能同时执行一条字节码指令,所以插入 dict 是原子操作,除非你自己实现了 __hash__ 方法。

maritimus 发表于 2022-12-6 19:11

锁就是锁,一个锁就可以,留multiprocessing那个
页: [1]
查看完整版本: python代码多线/进程性能问题