英文:
Open PE files with timeout in golang
问题
我想在Go语言中尝试使用超时打开一个PE文件。为了实现这一目标,我使用了匿名函数来通过通道传递文件指针和错误。我使用select语句和超时case来强制执行超时,代码如下所示:
go func() {
f, e := pe.Open(filePath)
file <- f
err <- e
}()
select {
case <-fileOpenTimeout:
fmt.Printf("ERROR: Opening PE file timed out")
return
case fileError := <-err:
if fileError == nil {
// ...
}
}
这段代码对我的用例效果很好。然而,如果文件打开时间过长,可能会导致资源泄漏。我该如何防止这种情况发生?有没有更好的方法来强制在打开PE文件时设置超时?
英文:
I want to try open a PE file with a timeout in Go. To achieve this, I am using anonymous function while channeling out the file pointer and error. I use the select clause with a timeout case to enforce the timeout as shown below.
go func() {
f, e := pe.Open(filePath)
file <- f
err <- e
}()
select {
case <-fileOpenTimeout:
fmt.Printf("ERROR: Opening PE file timed out")
return
case fileError := <-err:
if fileError == nil{...}
}
This code works fine for my use case. However, this may lead to resource leakage if the file takes too long to open. How can I prevent this? Is there a better way to enforce timeout on opening the PE file?
答案1
得分: 0
如果你有一个传递给匿名函数的done通道,你可以使用它发送一个信号,表示你提前结束了。
func asd() {
fileOpenTimeout := time.After(5 * time.Second)
type fileResponse struct {
file *pe.File
err error
}
response := make(chan fileResponse)
done := make(chan struct{})
go func(done <-chan struct{}) {
f, e := pe.Open(filePath)
r := fileResponse{
file: f,
err: e,
}
select {
case response <- r:
// do nothing, response sent
case <-done:
// clean up
if f != nil {
f.Close()
}
}
}(done)
select {
case <-fileOpenTimeout:
fmt.Printf("ERROR: Opening PE file timed out")
close(done)
return
case r := <-response:
if r.err != nil { ... }
}
}
当done通道关闭时,你总是能够读取到零值。因此,你的匿名函数不会泄漏。还有一个fileResponse结构体,它的作用域仅限于该函数,以简化从go协程返回多个值的传递。
英文:
If you have a done channel that's passed to the anonymous func, you can use it to send a signal that you've ended early.
func asd() {
fileOpenTimeout := time.After(5 * time.Second)
type fileResponse struct {
file *pe.File
err error
}
response := make(chan fileResponse)
done := make(chan struct{})
go func(done <-chan struct{}) {
f, e := pe.Open(filePath)
r := fileResponse{
file: f,
err: e,
}
select {
case response <- r:
// do nothing, response sent
case <-done:
// clean up
if f != nil {
f.Close()
}
}
}(done)
select {
case <-fileOpenTimeout:
fmt.Printf("ERROR: Opening PE file timed out")
close(done)
return
case r := <-response:
if r.err != nil { ... }
}
}
When the done channel is closed you will always be able to read the zero value. So your anonymous func won't leak. There's also a struct fileResponse that is scoped to only the function to simplify passing multiple values back from the go routine
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论