所有的,
func main() {
l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+ CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
done_flag := make(chan bool, 1)
// Handle connections in a new goroutine.
go func() {
conn.Write([]byte("string1\n"))
conn.Write([]byte("string2\n"))
...
}()
}
}
现在,我试图避免的是下面的连接语句代码,其中我将代码包装在goroutine中的错误处理中(类似于以下内容):
go func() {
if (_err := _send_ack(conn, "string1\n"); _err != nil {
done_flag <- true
}
if (_err := _send_ack(conn, "string2\n"); _err != nil {
done_flag <- true
}
}()
相反,如果存在连接问题,我宁愿将整个过程短路,然后立即以错误退出goroutine,我也不愿意担心如何构造代码。我也许可以进一步包装_send_ack并将通道作为函数参数发送--但是如果程序是高度分层的,这就变得不确定了。例如,我可能有一个由几个函数组成的goroutine,每个函数处理不同的tcp会话--我不想在子程序中添加额外的通道参数,以便在调用堆栈中上下推进通道,以防我必须设置完成标志。此外,还有一个问题是,在设置done标志之后,goroutine会发生什么,以及如何在调用方中处理它。
如果我使用的是python或perl或C++,我会抛出一个异常,该异常附加了一个错误发生的堆栈跟踪,然后在调用方中处理该错误。但是由于golang没有异常,我希望有一种方法可以在不退出主程序的情况下停止goroutine cold--即:设置一个通道,使其出现相关错误,然后在该点停止执行。
我看到了恐慌功能,但我不确定这样做的副作用。您能在不影响主程序的情况下panic()退出goroutine,或者有没有一种方法可以智能地短路goroutine,而不产生副作用,也许返回类似异常的东西,带有堆栈跟踪和错误?或者建议什么方法来干净地错误处理像这样的分层程序?
非常感谢你的帮助--我是golang的新手,这可能表明了。
艾德
golang建议使用显式错误而不是隐式异常。
// for code simplicity
func doSendACKImpl(conn net.Conn) error {
if err := _send_ack(conn, "string1\n"); err != nil {
return err
}
if err := _send_ack(conn, "string2\n"); err != nil {
return err
}
return nil
}
func main() {
l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+ CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// can change to self defined ResponseType, here use error for demo
workRes := make(chan error, 1)
go func() {
// return write back to channel
workRes <- doSendACKImpl(conn)
}()
select {
// read result back
case resError := <-workRes:
fmt.Printf("meet error %s", resError)
}
}
}
要获得更多的并发能力,请使用更大的通道缓冲区大小,并将处理结果处理程序移到另一个goroutine中
func main() {
l, _ := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
// more result buffer size
const workSize int = 100
// can change to self defined ResponseType, here use error for demo
workResBuffer := make(chan error, workSize)
// goroutine collect result
go func() {
// get all result from worker responses
for resError := range workResBuffer {
fmt.Printf("meet error %s", resError)
}
}()
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// TODO: limit the goroutine number
go func() {
// return write back to channel
workResBuffer <- doSendACKImpl(conn)
}()
}
}
我终于在我的程序中实现了Thread.interrupt()而不是Thread.stop()。然而,我不确定我做得好不好。 我有一个类,它扩展了Thread并声明了几个方法。每个方法都抛出InterruptedException(每个方法都执行I/O密集型操作,其中一些需要几分钟才能完成,因此我没有使用线程安全标志,因为该标志直到操作完成后才会被检查)。我还在这些方法的几个地方添加了以下代码来抛出
问题内容: 我最近一直在尝试使用logback,并且一直在Eclipse内部直接运行示例。当我这样做时,我注意到- 即使在我的静态方法结束之后(从Java驱动程序类内部),应用程序仍在运行。 最终,我确定Logback正在管理自己的线程,这些线程即使在我的主应用程序退出后仍保持活动状态。我四处搜寻一些解决方案,发现这是从Java内部显式关闭Logback的一种方式: 这真的是彻底关闭登录的唯一方法
问题内容: 一个没有stopServer功能的RMI服务器,可以正常工作。 每当被调用异常中的stopServer()抛出时 这是堆栈跟踪 即使我使用清理服务对象,情况也一样 有人可以提出一种干净的方法来停止服务器,这还会释放端口以供重用。 问题答案: 您需要存储结果并取消导出结果。目前,您正在尝试取消导出存根。
问题内容: 这是我的问题:我有一个对话框,其中包含一些用户可以更改的参数(例如,通过微调器)。每次更改这些参数之一时,我都会启动一个线程以根据新的参数值更新3D视图。如果在第一个线程正在工作时用户更改了另一个值(或通过单击微调箭头多次再次更改了相同的值),我想中止第一个线程(以及3D视图的更新)并启动一个新线程具有最新的参数值。 我该怎么做? PS:我的线程的方法中没有循环,因此检查标志不是一个选
我是Android Studio的新手,所以我面临一些问题。我正在寻找一种如何干净地项目的方法。 在Eclipse中,我会做<代码>项目-
怎么停止这个计时器,知道吗? 我想重置计时器在每个查询,但它继续。每个新的查询都会添加新的计时器。这个怎么解决?