--
--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina
---
您收到此邮件是因为您订阅了Google网上论坛上的“Golang-China”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到golang-china...@googlegroups.com。
要在网络上查看此讨论,请访问https://groups.google.com/d/msgid/golang-china/5db46473-1a29-4446-ba6b-40d16ff8bccc%40googlegroups.com。
要查看更多选项,请访问https://groups.google.com/d/optout。
On Dec 17, 2014 10:48 AM, "Hydra" <xxeag...@gmail.com> wrote:
> http://www.cnblogs.com/concurrency/p/4170657.html
> 这是我的一个小总结。
看了你的小结,有几个疑问要请教下:
1. “这个限制值目前是2000。如果超过就会抛出一个异常。这个是非常蛋疼的事情。而且从GO的ISSUE库里,这个问题的解决是一推再推。“ 请问你说的是具体哪一个issue?我刚才翻了翻,没找到。
2. 通过 cgo 或者 syscall 调用 dll 的导出函数的时候,对应的函数都会在操作系统提供的堆栈上执行(所谓的 m stack),而不会在 Go 的堆栈上执行,所以我认为你对于 chkstk 导致程序崩溃的原因分析得不正确。
3. 这个问题为啥不报告一个bug?当然,你得用先化简你的代码并且提供一个具体的重现步骤。我不用VS,所以没办法重现你的问题。但是如果真的是用了 chkstk 的 dll 和 Go 不兼容的话,那或许真是 Go 的问题。值得报告一个bug。
On Dec 17, 2014 9:54 PM, "Hydra" <xxeag...@gmail.com> wrote:
> 1. “这个限制值目前是2000。如果超过就会抛出一个异常。这个是非常蛋疼的事情。而且从GO的ISSUE库里,这个问题的解决是一推再推。“ 请问你说的是具体哪一个issue?我刚才翻了翻,没找到。
>
> https://code.google.com/p/go/issues/detail?id=1912 https://code.google.com/p/go/issues/detail?id=2193
> 我的想法是和1912里的观点一样,应该让用户回收掉这个CALLBACK。
> 但是2193里Alex说理应如此。
> 嗯,我夸大了事实...原谅我..
这俩issue不都关闭了么。callback是没办法回收的,Go怎么知道系统不会再调用某一个callback了呢?这个肯定只有用户才知道。
我说一下callback上限的原因。由于系统调用callback函数的时候不提供任何其他的参数,导致区分不同的callback只能通过被调用函数的地址,也就是说,一个Go的callback函数必须对应一个单独的C函数地址
旧的机制是对每个Go函数,在堆上动态构造一个对应的C函数。这样在 Go 1.1 之前的时候没问题,因为当时函数闭包也需要可执行的堆,但是 1.1 修改了函数的表示方式,闭包不再需要动态代码生成了,为了把 Windows 上也不再需要可执行的堆,必须想另外一个办法来实现 callback,新的机制参加 issue 5494,是我提议的。既然不动态生成代码,很明显的一个问题就是 callback 的总数会有一个上限。这是这有任何办法的了。
其实一般的 Windows 程序也不会有那么多 callback,2000个绝对是绰绰有余的;之所以 Go 这里很容易用光,是因为可能大家愿意使用 closure,而不是一个全局函数做 callback,使用全局函数做 callback (C/C++程序就是这么做的),2000个绝对是绰绰有余;但是由于闭包每次建立都是不同的,就算你其实就一个地方需要创建 callback,用闭包的话2000次就用光了所有的 callback。使用 callback 的时候建议用全局函数,也不要用 method,因为那样也是闭包,2000 个绝对足够足够。
嗯嗯,所以我说到就是自己把CALLBACK弄成全局函数来用。但是我真的想用闭包来搞,这样用起来更简洁。
难道不能提供FreeCallback这种东西么..
2. 通过 cgo 或者 syscall 调用 dll 的导出函数的时候,对应的函数都会在操作系统提供的堆栈上执行(所谓的 m stack),而不会在 Go 的堆栈上执行,所以我认为你对于 chkstk 导致程序崩溃的原因分析得不正确。附件GoDll导出了两个函数,一个是Test,一个是TestEx 两者功能一样,只是TestEx把rapidxml::xml_document放到了堆上构造,而前者是栈上构造。有一个简单的C++测试程序test,运行可以看到两个函数正常。godll.go是一个加载并调用两个函数的测试代码。可以根据参数callex决定是否调用TestEx,在我机器上TestEx正常,Test出错。另外还有两个xml,需要和godll.go编译的程序放在同一目录下。C++代码编译环境是VS2013 UPDATE4GO的版本是1.4 32位和64位都可以复现OS版本是WIN7 SP1