把 lua 和 event loop 结合起来,是不是比 js 更给力

2014-03-11 14:33:13 +08:00
 ryanking8215
js把event loop融入了它的血液了。从语法上看,lua和js相像的地方很多,大不同的地方是,lua都是同步接口,但所幸lua的core很小,是不是把它改动一下,结合libuv,也做成一个lua-async的东东,在通过luajit,是不是比js更给力?

当然,前后端大一统就没了。lua和c/c++结合比用v8简单太多了。

欢迎大家吐槽!
8428 次点击
所在节点    奇思妙想
28 条回复
clino
2014-03-12 12:48:21 +08:00
@ryanking8215 你保证是在一个线程里使用 goroutine 不就可以保证这个线程里的goroutine不会并行执行了嘛
用不用多线程或者多进程难道你不能决定吗?
ryanking8215
2014-03-12 13:17:41 +08:00
@clino goroutine和lua的coroutine还有gevent等这种协程是不同的概念。
协程生成在哪个线程上,就在哪个线程进行上下文切换,

但在golang里没有线程的概念,goroutine的这种设计屏蔽了操作系统的线程,目前的并发是使用线程来实现的,m个goroutine跑在n个线程上(m>=n),当你起goroutine时,golang的调度器负责将goroutie分配给已有线程或者新建线程。

你可以安装golang跑个例子看看
clino
2014-03-12 13:41:39 +08:00
@ryanking8215 我对go确实不了解,但刚才搜了一下应该也是可以配置的,而且应该是默认为单线程
http://blog.chinaunix.net/uid-22312037-id-3760407.html
" 默认情况下,调度器仅适用单线程,也就是说只实现了并发。想要发挥多核处理器的并行,需要在程序中显示调用runtime.GOMAXPROCS(n)告诉调度器同时使用多个线程。GOMAXPROCS设置了同时运行逻辑代码的系统线程的最大数量,并返回之前的设置。如果n<1,不会改变当前设置。关于并发和并行请参看rob的这篇文章"
ryanking8215
2014-03-12 14:02:01 +08:00
@clino http://golang.org/pkg/runtime/#GOMAXPROCS, 是设置多少个cpu参与并行,而不是线程数。

这篇东西完全在误导!

我刚才试了了一下:
func main() {
<- time.After(5*time.Minute)
}
简单的定时器,golang帮我开了5个线程,包括主线程,通过ls /proc/<pid>/task/查看
clino
2014-03-12 14:52:54 +08:00
@ryanking8215 看起来我给的这篇是不靠谱,goroutine确实和coroutine差别比较大,我之前想当然了
我想弄个go来试试,不过到现在没下载完

又搜到一篇: http://xiezhenye.com/2012/08/%e5%86%8d%e6%8e%a2-goroutine.html

"goroutine 并不是像我之前认为的,在 cgocall 或者 syscall 的时候进行自动切换,而是使用了线程。同时,这个线程数和 runtime.GOMAXPROCS 也没有直接关联。在这个情况下,虽然 runtime.GOMAXPROCS 设为了 2 ,但是最后照样用了 1000 多个线程。但是 strace -f ./par 直接运行,此时跟踪线程数,最多就只有几十个。看来和 less 也有关系"

"go 语言要避免大量线程产生的切换开销,用类似 coroutine 的方式,还是得结合异步 io 。但是目前只在网络 io 上实现了这点。对于其他的 io,比如文件系统,仍然会由于阻塞而产生线程。如果应用中需要使用文件 io,就得使用生产者消费者模式来减少线程数量,或者可以考虑利用 netfd 的代码来实现一个其他类型 io 的异步包装(当然功能上会有一些限制)"
ryanking8215
2014-03-12 15:18:36 +08:00
@clino 他说的是对的,第一段的“同时,这个线程数和 runtime.GOMAXPROCS 也没有直接关联。在这个情况下,虽然 runtime.GOMAXPROCS 设为了 2 ,但是最后照样用了 1000 多个线程。”,这句话没错,但是本来这2个就没有关系,并发和并行是2个概念,一个cpu可以通过开启n多个线程/进程并发或使用多个协程并发或使用event_loop并发,但不是并行计算,因为只有一个cpu,多个cpu参与就可以并行计算,多线程/多进程模型可以支持并行,但协程和event_loop就不支持了。

第二段说的包装io,libuv就封装了异步的io,是通过线程来实现的,毕竟filesystem io是block的。

goroutine把并发和并行结合了起来,而且不造成过多负担,模型一致。

我这样理解的并发(cocurrency)和并行(parallel):并发是逻辑上的“并发”,并行是物理上的“并发”。
clino
2014-03-12 16:13:16 +08:00
@ryanking8215 感觉很奇怪
如下代码,如果是只有一个go func() ,我这里是4个线程,如果有3个 go func(),则变成3个线程
不知道go内部是啥逻辑

func main() {
runtime.GOMAXPROCS(1)
go func() {
time.Sleep(3*time.Second)
fmt.Println("Hello, World. after 3 seconds")
}()
go func() {
time.Sleep(4*time.Second)
fmt.Println("Hello, World. after 4 seconds")
}()
go func() {
time.Sleep(5*time.Second)
fmt.Println("Hello, World. after 5 seconds")
}()

time.Sleep(6*time.Second)
fmt.Println("end")
}
ryanking8215
2014-03-12 16:32:34 +08:00
这个是golang的调度器实现的,具体的我也不懂了,没研究过。

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

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

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

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

© 2021 V2EX