Lua coroutine vs Java wait/notify
在上文Lua coroutine 不一样的多线程编程思路 中想到coroutine的运行机制跟Java中的wait/notify很相似,所以写了一个简单程序比较一下。 源代码Lua code co = coroutine.create(function(loops) for i = 1,loops do coroutine.yield() end end) local x = os.clock() local loops = 100 * 1000 * 1000 coroutine.resume(co,loops) for i = 1,loops do coroutine.resume(co) end print(string.format("elapsed time: %.2fn",os.clock() - x)) Java code public class TestWait { public static void main(String[] args) { WaitClass wc = new WaitClass(); wc.start(); int loops = 100 * 1000 * 1000; long t1 = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { synchronized (wc) { wc.notify(); } } long t2 = System.currentTimeMillis(); System.out.println("elapsed time: " + (t2 - t1) / 1000l); } } class WaitClass extends Thread { public void run() { while (true) { synchronized (this) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } 运行结果Lua elapsed time: 53.36 CPU占用运行环境:4core XEON Lua 1CPU 100%,其他CPU0%,total 25% (其中CPU sys 0%) Java 2个CPU 40%-50%,其他CPU 0%,total 25% (其中CPU sys 5%-10%) 从结果看,coroutine只利用了一个CPU,和原理所说完全一致。 Java利用了2个CPU,各占用了50%的CPU时间运行和50%的时间等待,和设计也一致。另外Java用了5-10%的sys CPU时间用于线程context switch 结论虽然这两种程序没有直接可比性,但仍然可以看出一些有趣的地方:
再谈coroutine应用场景今天又看到qiezi的文章并发编程模型:Thread,Coroutine,Callback … 分析得很深入,对这方面感兴趣的可以进一步去深入了解。 另外qiezi在Coroutine在并发程序中的应用中提到四种场景,可以理解是对我上篇文章对coroutine应用场景的一种答案。
但是我还是觉得存在疑虑,后面几种我觉得用多线程/线程池模式也可以很好解决。其实select/epoll异步IO方式跟多线程并不矛盾。多线程并不代表每个线程需要recv阻塞在那里。目前网络服务器的多线程通常是指业务逻辑处理部分使用多线程。比如Java中用mina来处理连接(相当于epoll),mina在收到数据包之后再分发给负责业务逻辑的thread pool处理。如果是CPU密集型任务,简单把线程池的线程数设成CPU数即可达到性能最佳。这时如果把线程数设成1,就很类似coroutine模式了。而Java模式所增加的消耗,主要是new runnable class以及线程池调度的开销。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |