Python 程序的大量时间消耗在了 lock.acquire 和 time.sleep 上面了,有办法优化吗

2018-06-29 11:04:29 +08:00
 misaka19000

在执行 Profile 的时候发现大量的时间消耗在了这两个方法上,个人认为主要原因在于如下的代码:

event = threading.Event()

socket.write(data)
while request_id not in results:
    event.clear()
    event.wait()
result = results[request_id]
print result
result = socket.read()
results[request_id] = result
event.set()

上面代码的目的是为了把异步的网络请求转为同步请求,客户端在请求发出去之后就进入阻塞状态,直到服务端的响应返回值后,我在读取数据到 results 之后唤醒请求线程,之后请求线程继续执行。

我有两个问题想请问下各位大佬:

  1. 上面的代码是产生图片中方法时间消耗的原因吗?
  2. 上面的代码会对性能产生影响吗,影响有多大?
  3. Python 有没有什么更好的方式来实现异步的通信转为同步呢?

谢谢大家!!!😋

5302 次点击
所在节点    Python
18 条回复
dbow
2018-06-29 11:16:20 +08:00
用 coroutine
```python
async def hello():
print("Hello world!")
r = await asyncio.sleep(1)
print("Hello again!")
```
NoAnyLove
2018-06-29 11:20:26 +08:00
游泳健身,了。。。。。。哦不是,asyncio 了解一下
lieh222
2018-06-29 11:23:57 +08:00
啤酒饮料矿泉,水。。。。。。哦不是,asyncio 需要吗
lfzyx
2018-06-29 11:28:11 +08:00
这个图片是用什么工具生成的
locoz
2018-06-29 13:06:00 +08:00
@lfzyx pycharm 的功能吧
wwqgtxx
2018-06-29 13:19:19 +08:00
这种异步转同步有大量锁的等待很正常呀,Event 本来就是用 lock 实现的,对性能影响不大,要是真的那么在乎这一点性能,用 asyncio 或者 gevent
misaka19000
2018-06-29 13:31:11 +08:00
@dbow #1
@NoAnyLove #2
@lieh222 #3
@wwqgtxx #6
python2 不支持 asyncio 呀。。。
misaka19000
2018-06-29 13:32:36 +08:00
@lfzyx #4 PyCharm 在 run 的时候有一个 Profile 选项,用那个选项来运行就行了
tonic
2018-06-29 18:24:01 +08:00
那么 eventlet / gevent 了解一下...
tonic
2018-06-29 18:24:36 +08:00
等下我看反了... 你要异步变同步... = =!
aaronzjw
2018-06-29 18:27:16 +08:00
用协程
misaka19000
2018-06-29 18:35:31 +08:00
@aaronzjw #11 大佬能不能再详细的介绍介绍啊,萌新不太理解啊。。。
lolizeppelin
2018-06-29 20:15:38 +08:00
你要干啥 如果是 socket 收数据
收好的数据塞队列里
然后另外一个线程从队列里取就完了

不要没事就加锁
misaka19000
2018-06-29 21:16:23 +08:00
@lolizeppelin #13 但是请求是同步的,我得在前端知道数据是否已经获取到了啊。。。
ryd994
2018-06-29 23:36:49 +08:00
要性能的话可以自己实现协程
做个等待表
有结果回来的话就查表唤醒等到中的线程不就好了么?
再进一步,加上回调函数,有结果的话调用回调

我怎么觉得比你写这一套还要简单点?
misaka19000
2018-06-29 23:48:33 +08:00
@ryd994 #15 谢谢,我再琢磨琢磨,有不懂的再向您请教😋
NoAnyLove
2018-06-30 10:16:08 +08:00
eventlet 了解一下,另外,你是所有线程共享同一个 event ?
misaka19000
2018-06-30 10:28:13 +08:00
@NoAnyLove #17 是的,是所有的线程共享一个 event

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

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

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

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

© 2021 V2EX