在golang中使用超时打开PE文件

huangapple go评论120阅读模式
英文:

Open PE files with timeout in golang

问题

我想在Go语言中尝试使用超时打开一个PE文件。为了实现这一目标,我使用了匿名函数来通过通道传递文件指针和错误。我使用select语句和超时case来强制执行超时,代码如下所示:

  1. go func() {
  2. f, e := pe.Open(filePath)
  3. file <- f
  4. err <- e
  5. }()
  6. select {
  7. case <-fileOpenTimeout:
  8. fmt.Printf("ERROR: Opening PE file timed out")
  9. return
  10. case fileError := <-err:
  11. if fileError == nil {
  12. // ...
  13. }
  14. }

这段代码对我的用例效果很好。然而,如果文件打开时间过长,可能会导致资源泄漏。我该如何防止这种情况发生?有没有更好的方法来强制在打开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.

  1. go func() {
  2. f, e := pe.Open(filePath)
  3. file &lt;- f
  4. err &lt;- e
  5. }()
  6. select {
  7. case &lt;-fileOpenTimeout:
  8. fmt.Printf(&quot;ERROR: Opening PE file timed out&quot;)
  9. return
  10. case fileError := &lt;-err:
  11. if fileError == nil{...}
  12. }

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通道,你可以使用它发送一个信号,表示你提前结束了。

  1. func asd() {
  2. fileOpenTimeout := time.After(5 * time.Second)
  3. type fileResponse struct {
  4. file *pe.File
  5. err error
  6. }
  7. response := make(chan fileResponse)
  8. done := make(chan struct{})
  9. go func(done <-chan struct{}) {
  10. f, e := pe.Open(filePath)
  11. r := fileResponse{
  12. file: f,
  13. err: e,
  14. }
  15. select {
  16. case response <- r:
  17. // do nothing, response sent
  18. case <-done:
  19. // clean up
  20. if f != nil {
  21. f.Close()
  22. }
  23. }
  24. }(done)
  25. select {
  26. case <-fileOpenTimeout:
  27. fmt.Printf("ERROR: Opening PE file timed out")
  28. close(done)
  29. return
  30. case r := <-response:
  31. if r.err != nil { ... }
  32. }
  33. }

当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.

  1. func asd() {
  2. fileOpenTimeout := time.After(5 * time.Second)
  3. type fileResponse struct {
  4. file *pe.File
  5. err error
  6. }
  7. response := make(chan fileResponse)
  8. done := make(chan struct{})
  9. go func(done &lt;-chan struct{}) {
  10. f, e := pe.Open(filePath)
  11. r := fileResponse{
  12. file: f,
  13. err: e,
  14. }
  15. select {
  16. case response &lt;- r:
  17. // do nothing, response sent
  18. case &lt;-done:
  19. // clean up
  20. if f != nil {
  21. f.Close()
  22. }
  23. }
  24. }(done)
  25. select {
  26. case &lt;-fileOpenTimeout:
  27. fmt.Printf(&quot;ERROR: Opening PE file timed out&quot;)
  28. close(done)
  29. return
  30. case r := &lt;-response:
  31. if r.err != nil { ... }
  32. }
  33. }

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

huangapple
  • 本文由 发表于 2017年5月12日 07:47:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/43927276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定