大家说一下 多线程 协程 在实际项目中的应用场景

2018-05-11 00:16:23 +08:00
 xiaoshi657

想了解一下实际项目中的应用场景,看教程举的列都是用 time.sleep()模拟的

14397 次点击
所在节点    Python
24 条回复
crb912
2018-05-11 00:27:17 +08:00
比方说苹果的 heic 图片,里面有 48 个编码的图块。解码时如果逐个(一个个的图块)解也可以,但是多线程并行处理快的多。

使用多线程并行处理,无非想要提高应用的性能和速度。
WordTian
2018-05-11 00:31:35 +08:00
比如 web 服务器,一个端口,很多用户同时连接,不用多线程难道让后面的用户等着吗?
shijingshijing
2018-05-11 00:34:34 +08:00
我举个简单的例子吧,已知户外有一个温度传感器,这个传感器自带控制器能够 30 秒刷新一次温度值并通过以太网广播出去。订阅这个广播的有很多个用户,比如有一个服务器每收到一次传来的温度值就加上时间戳然后存入数据库中;还有一个户外公告牌用于展示温度值,每次收到以太网的广播数值之后就更新显示。

现在我在 PC 上设计了一个简单的界面来显示这个数值,UI 本身占了一个线程,该线程负责 UI 的控件显示和刷新;这时候我还需要另外一个线程来监听以太网的广播,这两个线程是不能做到一起的,否则 UI 会挂起失去响应。

监听广播的线程跑着一个 while ( true )的循环,一旦有更新就触发 event 给 UI 线程进行更新。UI 线程会在收到 event 之后对显示的温度值控件进行更新。
agagega
2018-05-11 00:51:22 +08:00
线程:

1.如果你的 CPU 有多个核,多线程可以利用操作系统的调度机制,让这若干个核同时计算,提高效率。当然多进程的方法也可以利用多核,两者的区别不赘述了。
2.即使没有两个核,如果你在做一个带用户界面的程序,单线程就意味着你在做某些耗时计算或者 IO 的时候程序界面会卡住。因此分离界面线程和 IO 或计算线程是有利的。
3.类似地,如果你需要同时处理多个 IO 请求(并发),即使你没有多核,多线程也可以利用操作系统的调度机制,不让计算资源闲置。

协程:

你可以去了解一下 JavaScript 的生成器( Generator )。事实上,前面提到的 3 或许根本不是解决并发问题的好方案——如果同时有十万个请求,我们要开十万个线程吗?当然,另一个解决方案是把线程做得轻量化,彻底运行在用户空间,即所谓的 M:N 模型,具体例子就是 Go 语言的 goroutine。
momocraft
2018-05-11 00:54:01 +08:00
一核有難八核圍觀.png
orangeade
2018-05-11 00:59:51 +08:00
对比下 requests 和 aiohttp,效率的差别
ericls
2018-05-11 04:51:42 +08:00
@agagega 多线程 绕不开 GIL

多线程可以共享内存
多进程不共享内存 通过消息传递信息
Leigg
2018-05-11 05:02:31 +08:00
python 的 gil 会在程序等待 io 的时候释放,所以 python 的多线程可以提高 io 密集型任务的执行效率,如从一个接口下载 10000 张图片。
lihongming
2018-05-11 07:37:14 +08:00
多线程不仅是性能问题,不用多线程的话可能连功能都无法实现。
比如我做的一个视频监控,每隔 0.03 秒截一张图并识别里面有无目标,有就播放一个嘀嘀嘀的声音提醒监控人员。
如果没有多线程,那在嘀嘀声播放完以前,是无法继续截图识别的,这就产生了半秒左右的失控期
araraloren
2018-05-11 08:16:36 +08:00
@crb912 是并发。。。
lianxiaoyi
2018-05-11 09:03:22 +08:00
举个我实际用的案例,我有 10000 多个文件是以压缩包形式存在硬盘,我现在需要把这些文件去进行解压然后将文件内容做一个转换,单线程肯定会慢,那么就可以先把所有文件路径放入 list,启动很多线程,每个线程去 list 中取当前最新文件路径并在 list 中删除当前文件路径,然后去执行相同的任务代码!以前一个人干的事,瞬间变成了 20 个人干甚至更多!大大加快了速度!
zhujinliang
2018-05-11 09:06:26 +08:00
抬个杠…楼上说的某些场景不用多线程也能做…
比如轮询每个连接、使用状态机处理并发请求,比如 9#的例子我可以严格控制时间,播放音乐时每 0.03 秒检查声卡缓冲区并往声卡缓冲区写足够的数据。
我觉得多线程好处一个是可以利用多核并行处理能力,另一个是编写、调试直观,执行到哪句就是处理到哪个步骤。状态机的话得先编好状态表,调试得一步步跟状态,脑内模拟状态跳转。
misaka19000
2018-05-11 09:20:14 +08:00
@zhujinliang #12 其实最重要的是多线程明显降低了开发者的开发难度,线程是 OS 提供给用户的一套更加强大的 CPU 使用策略;当然 OS 本身还支持多进程,这是为了实现多个程序都能在平台上运行,不过这又是另外一个话题了
Hopetree
2018-05-11 09:37:54 +08:00
多线程爬虫,比如,你要爬 100 万个 URL,每个 URL 的请求要耗时 2 秒,如果你用单线程,你要花费的时间是至少 100 万*2,但是我可以用多线程去爬,开 100 个线程啊,100 个线程没人自己去拿 URL,然后去请求,才不要管其他线程有没有结束,最后就是处理请求结果的事情了,那是后话。反正这种耗时的 I/O 密集型就用多线程,可以提高效率
vicalloy
2018-05-11 10:02:14 +08:00
很多时候系统瓶颈都在 IO,很多涉及到 IO 特别是网络的程序都需要用到线程 /协程。
比如你写个 V2EX 的客户端,如果不用多线程,用户点击登录,在请求网络接口的这段时间里界面都会卡死。
MeteorCat
2018-05-11 12:48:57 +08:00
skynet
muduo
nonesuccess
2018-05-11 12:55:44 +08:00
记着学操作系统的时候教材里有一句,并行程序的初衷是在单个 cpu 上运行
neoblackcap
2018-05-11 16:49:41 +08:00
这个问题应该是这样看,线程更多是抢占式线程,协程是协作式线程。我们暂时不考虑是有栈还是无栈的区别
那么协程跟线程的区别更多在于你觉得哪个调度策略更高效。操作系统还是开发者。协程上下文切换现在是在用户空间,因此调度的成本相对较低。不过也不代表这就是高效的。
我们可以笼统地认为在面对 IO 密集型任务的时候,协程更高效,因为绝大部分时间都是在等待 IO。
而面对 CPU 密集型的任务,线程更高效

然而 Python 的常规实现因为有 GIL 的存在,你可以认为协程吊打线程。但是仅在 CPython 跟 PyPy 这些实现里面,千万不要认为是定律

建议多读读操作系统相关的书记,比如《现代操作系统》,同时了解一下 M:N, 1:1 等线程模型,你会了解到更多
crb912
2018-05-11 18:56:42 +08:00
@araraloren 抬出去。又一个并发和并行搞不清的ㅍ_ㅍ
你可以看看这篇文章
https://blog.csdn.net/Bruce_0712/article/details/65937691
ycz0926
2018-05-11 19:02:45 +08:00
还是得看应用呀?
嵌入式设备上,能简则简,多线程反倒会拉高 cpu,老老实实写几行同步的代码,效率也高
web 后端,倒是可以试试,不过好像基于协程的项目确实不多,可能是本人孤陋寡闻

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

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

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

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

© 2021 V2EX