2014-09-11 32 views
0

在Go中,go是产生goroutine的关键字。但是,似乎关键字没有返回任何值,那么如何检测goroutine是否正确产生?如何检查goroutine是否成功创建?

看来Go使用以下方法来检查func是否成功。

value, err = myFunc(value) 

go关键字是否有类似的用法来检测创建错误?看起来go如果失败就会抛出一个运行时异常。

我想做一个测试,找出我可以为CPU创建的最大goroutine数量。

+2

你的问题意味着产生一个新的goroutine可能会失败,实际上有时会失败。是什么让你认为这个假设是真的?当然,任何事情都可能会失败(只需拔掉CPU或RAM),但在这种情况下,您将无法检查这些问题。对我来说,你的问题似乎在问“如何检查'a + = 1'是否成功?” – Volker 2014-09-11 06:20:57

+0

@Volker在给定的时间内,你可以拥有多少个goroutines是有上限的。实际上,甚至估计上限并不难。 – 2014-09-11 07:44:46

+0

Volkerless,我认为案件不同于“a + = 1”。想象一个游戏服务器,从客户端到服务器的连接是很长时间的连接,所以需要维护客户端的每个状态,并且goroutine有自己的可以闪烁或增长的栈,所以最大的在线游戏用户限于goroutine的总内存使用情况。 – python 2014-09-11 10:22:13

回答

2

正如你已经知道:

value, err = myFunc(value)

是通过返回来处理异常的惯用方式内置error类型。我想你可以通过某种方式将它与检查的异常进行比较。但就你而言,未能产生新的goroutine更多的是运行时异常。 golang如何处理这些是通过使用panics。您可以使用内置的recover()函数在代码中处理它们,该函数将尝试重新获得对执行流程的控制权。如果没有这个,panic将上升到堆栈,直到它崩溃程序。

注意recover()具有其中为defer ED的函数被调用,这些功能被压入到一个列表,并在它们被延迟执行的函数的结束始终称为 - 所以即使当panic发生他们将被打电话,让您拨打recover()。如果你只是在你的函数结束时尝试调用recover()(或者在你恐慌子函数后的任何地方),执行将永远不会达到它。如果您可以处理恐慌(recover()不会返回err),以便您的程序可以实际上继续执行,它将从引发恐慌的功能开始执行。

认为上面的博客文章是足够的,但如果你需要更多的例子只是在这里评论。

此外,您的系统最有可能以RAM存储器而非CPU为界。

+0

感谢您的回答。所以有其他的最佳做法来检测“去”关键字失败,而不是运行时异常?因为在C中,malloc/free这种内存不足不会抛出异常而是一个NULL指针。 – python 2014-09-11 03:01:54

+0

@python你真的不能这么做,如果你非常偏执,那么你可以添加很多像''this'这样的延期(http://play.golang.org/p/VQWh7yozKx),但你真的应该别担心。 – OneOfOne 2014-09-11 03:23:57

+4

另一个角度:'go'只是分配几KB的一小段堆栈,并在调度器中做一些事情。如果你不能为调度程序控制结构分配几个KB或空间,那么你的程序真的是非常糟糕;这种情况只能用于预防,不能从中恢复。 – twotwotwo 2014-09-11 03:31:15

1

goroutine创建(或多或少)只是一个内存分配。一般情况下你不能捕获内存分配异常,这与goroutines是一样的。

如果你的程序内存不足,除了退出和重新启动之外,通常没有什么可以做的。

+0

hi rog,如果goroutine可以在调用失败的情况下返回一些值,就像C++ new/malloc一样,它通常会返回NULL指针而不是抛出异常,这听起来很合理。如果golang游戏服务器想要保存用户的所有连接,那么听起来合理,如果“go”失败,返回一些内容 – python 2014-09-12 02:43:36

+1

为什么“go”语句是特殊的?还有许多其他地方都是隐含分配的。例如,将字符串分配给接口{}进行分配 - 它怎么会返回一个值?调用一个函数也可以分配(堆栈帧被分配)。我们不希望Go变得像C,你需要检查每个分配。 你想让你的测试告诉你什么? – rog 2014-09-12 08:28:51

0

如果您正在使用的函数返回错误的执行例程,您可以调用匿名函数并处理匿名函数中的错误。

go func() { 
    value, err := myFunc() 
}()