1
zhangxiao 2012-09-22 09:57:45 +08:00
所以说异步编程和多线程其实是同一层面的概念对吗?是不同的实现“并行”的方式?
|
2
guotie 2012-09-22 10:19:39 +08:00 1
不是。
|
5
darklowly 2012-09-22 11:13:11 +08:00 1
@zhangxiao
多线程和异步两个不同的概念噢 异步一般情况下,都是指IO部分。在执行IO的时候不用等待了。包括定时器,包括键盘鼠标事件,都可以认为是IO。 IO的时候不等待了, 所以在该线程就不会阻塞了。本质上也只能提高IO部分的CPU吞吐率。 多线程 就是拿多个CPU来跑,所以提高吞吐率是必然的。(前提是你有多个CPU) |
6
sivacohan 2012-09-22 11:53:13 +08:00
@darklowly 你对多线程的解释貌似不太对吧。线程可以视为轻量级的进程,创建线程的开销比创建进程的开销要小。进程的数量和CPU数量没关系,线程也没关系啊。linux下创建进程可以fork,线程我不知道……
|
7
guotie 2012-09-22 13:53:03 +08:00
我感觉,异步这个概念的范围很广,很模糊,很多情况都可以成为异步;线程就是操作系统中的相对于进程的概念,很明确。
另外,异步、同步应该是从结果上来区分,线程、进程是从手段上区分。 |
8
darklowly 2012-09-22 19:23:18 +08:00 2
@sivacohan 我想是你没明白我的意思,或者是你对线程的理解有问题。
操作系统管理进程和线程的基本思想是分时 在单核上面 多进程和多线程还是在一个CPU上跑。所以这个时候你创建多进程或者是多线程,可以让很多工作同时做了,但是 本质上不能提高CPU的吞吐率。 在多核上跑,多线程和多进程就能同时跑。但是当你同时运行的进程或线程数量超过你CPU的个数的时候,就和单核类似了。 从进程和进程之间的关系来讲 分时的主要目的是可以同时运行多个程序。现在觉得没什么了。很多年前是很先进的。 对于一个具体的进程内部,线程和线程之间的关系,其实差不多,唯一区别就是他们位于同一个地址空间 还有线程虽然比进程轻量级。但是开销还是蛮大的。所以现在的网络服务器很多都开始通过多线程+异步模式来做。这样一来可以通过多线程提高多核CPU的吞吐率,二来异步模式可以防止线程数量过大时线程本身的开销过大 所以就导致了楼主这样的人分不清 线程和异步。本质上他们是在从不同的角度提高吞吐率。但是又完全是两个完全不一样的技术。 |
9
darklowly 2012-09-22 19:32:40 +08:00
修正上面的话。不是楼主 是一楼。。。。。
|
11
zhangxiao 2012-09-22 23:08:39 +08:00
@darklowly 那么在单核的机器上就不可以跑多线程的程序了?还是说跑是一样跑的,只是效率实际上没有提升,因为其实还是在单核上分时跑的?
换个场景,记得最早写带UI的程序的时候,都是让UI跑在一个单独的thread,程序逻辑跑在另一个thread,因为要等待用户交互,有阻塞。这个地方的多线程貌似和你解释的多线程不是一个东西吧? |
12
harmy 2012-09-23 00:47:57 +08:00 1
异步和同步可以拿麦当劳和肯德基的排队点餐做比喻。肯德基的排队点餐是同步的,因为一个每个服务员负责点餐、收银、配餐,服务好你之前,你后面的顾客只能等待;麦当劳的排队点餐是异步的,服务员给你点完餐收完银之后就让你在旁边一列等,把你交给配餐员了,你后面的顾客此时就可以点餐了。
|
13
darklowly 2012-09-23 07:35:39 +08:00
@zhangxiao 在你的CPU没有爆满之前,多线程或多进程可以让你同时干几个事情。
对于同一个程序。多线程可以把UI线程解脱出来,避免UI线程阻塞 我这里说的是吞吐率,当你的负荷很大的时候,如果线程太多,反而会越来越增加负荷。你平时用电脑的时候CPU负荷很低,不要用表象来看待内部。 |
14
raptor 2012-09-24 18:23:13 +08:00 2
顶楼明明是在说Twisted,底下评论怎么就为了线程和异步twist起来了……
其实我觉得twisted已经有点out了,因为它的异步实现还是太扭曲,用起来太痛苦,反正我是已经改用gevent了,greenlet最高。 多线程和异步这样理解应该比较简单: 多线程本质上是OS划分时间片,把CPU分时提供给各线程使用。 异步(多协程)本质上是有一个调度器,在协程进行IO操作需要等待的时候分时切换CPU。 区别就在于: 线程中你不知道OS会在什么时候切换,所以每个线程必须自己小心处理临界量,以防死锁,而且时间片划分过小,则切换成本过高,所以线程开太多性能反而会下降。 在异步的情况下,只有IO的时候会发生切换,所以实际上除了IO以外的所有操作都相当于是“原子”操作,基本不会死锁。而且因为IO操作没有那么频繁,切换成本较低,在一个进程里开非常多的协程也问题不大。 但也不是说异步就完美。 在多核时代,多线程可以充分利用CPU资源。并且线程的切换是强制的,即使某个线程有问题(比如死循环),也不至于阻塞别的线程。 异步本质上是单线程,要利用多核的话通常只能使用多进程(GO语言据说现在在搞支持多线程的方案,但据说效果不是很好),另外,如果某个协程没有IO操作,那么其它协程就会被阻塞。 总体来说,线程适合计算密集型应用,异步适合IO密集型应用。 |
18
raptor 2012-09-25 22:30:27 +08:00
好吧,这么说的确有理。
异步并不是只有协程一种实现方式,Twisted和Tornado都是用回调实现的。 不过协程并不一定是语言级别的,greenlet就是一种非语言级别的协程实现。 |
19
ch_linghu 2012-09-26 16:27:00 +08:00 2
异步和同步是相对的概念,用来描述工作的流程。同步的任务有明确的时序,异步不要求任务有明确的时序。至于同步和异步的具体实现,其实是不一定的。
同步流程也可以用多线程、多进程甚至多设备实现。比较典型的比如传统的网络请求应答,就是一个同步流程,但是是在两台设备上实现的。 同样的,异步也可以用单线程实现。gevent的协程就是典型的单线程异步流程实现方式。 线程是一个单机上的并行模型。因为其并行特性,用来实现异步流程是一个比较自然的想法。但线程由于其不可控性,在处理临界量方面确实会增加复杂性。另外线程的产生和切换代价都比较高,不适合大规模使用。所以才会有基于事件切换的比如回调模型、协程模型等更轻量的方式,但要注意的是,回调和协程这些并不是并行执行的。 |
20
raptor 2012-09-26 16:28:46 +08:00
顶楼上意见。哈哈
|
21
dhysum 2012-09-26 16:35:14 +08:00
线程和异步是两个摡念,没有可比性!
|
22
fanzeyi 2012-09-26 17:41:29 +08:00
=.= 写 LPC 的时候一直在幻想用 Python 写……
|
23
skywinger 2012-09-26 18:01:00 +08:00
哈哈,2000的时候,JAVA没有NIO库,NIO就是为了异步IO方式而设计的。
|
24
skywinger 2012-09-26 18:03:21 +08:00
目前JAVA的NIO可以使用linux系统内核的epoll方式的IO操作,比select 异步IO还要高效。
|
27
sillyousu 2012-09-26 19:14:22 +08:00
Twisted Introduction
This multi-part series introduces Asynchronous Programming and the Twisted networking framework. http://krondo.com/?page_id=1327 |
29
jamiesun 2012-09-26 20:57:00 +08:00
协程比异步要高级一点。
|
30
skywinger 2012-09-26 23:23:47 +08:00
其实,windows平台也不错,除了异步IO接口以外,还有complet port(完成端口)、AsyncEventSocket、AsyncSelectSocket等。
|
31
yegle 2012-09-27 09:54:06 +08:00
求对比thread和greenlet…
|
35
jjx 2012-11-07 21:03:46 +08:00
twisted 在windows下用cython实现了iocp的,gevent可没有
twsited 框架设计可说是工业级的,服务异常稳定,不会奔溃,用过都有感觉 gevent 大magic 了,我个人还是比较喜欢更明确的异步写法 |
36
myrual 2012-11-07 21:30:58 +08:00
以我的感受来说,twisted把tcp 网络编程需要考虑的三个场景都提供了简单的接口供你发挥。建立链接,接受数据,断开链接。
|
37
phuslu 2012-11-08 12:18:53 +08:00
楼上的兄弟把 twisted 的好处都说完啦, 不过 callback 那种缠绕式的代码还是挺郁闷的, 这也是 gevent 能流行起来的原因, 有句话不是说么 twisted is twist.
新版的 tornado/twisted 都有 yield/generator 风格的异步调用来简化 callback 了. 我觉得类似 gevent 这种 "同步代码异步运行" 的方式是深得人心的. http://mail.python.org/pipermail/python-ideas/2012-October/016424.html |
38
HowardMei 2012-11-08 12:24:15 +08:00
|
39
phuslu 2012-11-08 12:42:48 +08:00
@HowardMei 没找到他的 benchmark 代码, 不过我对 gevent 比 tornado 慢 这个结果有点怀疑.
|
40
HowardMei 2012-11-08 14:27:10 +08:00
|
41
jjx 2012-11-08 16:30:33 +08:00
@HowardMei cycone底层还是twisted, 和torando比,在windows 平台下我是推荐cycone而不是tornado,就是我刚才提到到twisted iocp支持的缘故,并发越高,iocp 的优势越明显,比windows默认的select有一倍到几倍的差距
|
42
BigZ 2012-11-08 17:04:22 +08:00
twisted 10年前还不错,现在多了很多选择
做http,可以用tornado 做tcp,可以用nodejs twisted比较好的地方是那些calllater 函数,这点nodejs很完美支持的 |