Golang:如何将代码与线程绑定?

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

golang: how to bind code with thread?

问题

我已经几乎实现了一个人脸识别的Go服务器。我的人脸识别算法使用了caffecaffe是一个线程绑定的图形库,这意味着我必须在同一个线程中初始化和调用算法,所以我查看了LockOSThread()

LockOSThread只使用了一个线程,但是我的服务器有4个GPU。

C/C++中,我可以创建4个线程,在每个线程中初始化算法,使用sem_waitsem_post来分配任务,一个线程使用一个GPU。

Go中如何做到同样的事情,如何将代码与线程绑定起来?

英文:

I have nearly implemented a face recognition Go server. My face recognition algorithm uses caffe, caffe is a thread-binding graphical library, that means I have to init and call algorithm in same thread, so I checked LockOSThread().

LockOSThread uses 1 thread, but my server owns 4 GPU.

In C/C++, I could create 4 threads, initialize algorithm in each thread, use sem_wait and sem_post to assign task, 1 thread use 1 GPU.

How to do the same thing in Go, how to bind code with thread?

答案1

得分: 4

你生成了一些goroutine,在每个goroutine中运行runtime.LockOSThread(),然后在每个goroutine中初始化你的图形库。

然后,你使用常规的Go通信原语将任务发送到这些goroutine中。通常,最简单的方法是让每个goroutine从一个通道中读取“任务”,并将结果发送回去,就像这样:

type Task struct {
  Data DataTypeToContainRecognitionTask
  Result chan<- DataTypeToContainRecognitionResult
}

func GoroutineLoop(tasks <-chan Task) {
  for task := range tasks {
    task.Result <- recognize(Data)
  }
}

tasks := make(chan Task)
for n := 4; n > 0; n-- {
  go GoroutineLoop(tasks)
}

for {
  res := make(chan DataTypeToContainRecognitionResult)
  tasks <- Task{
    Data: makeRecognitionData(),
    Result: res,
  }
  
  result <- res
  // 对结果进行处理
}

至于确定要启动多少个goroutine,有不同的策略。最简单的方法可能是查询runtime.NumCPU()并使用这个数字。

英文:

You spawn some number of goroutines, run runtime.LockOSThread() in each
and then initialize your graphical library in each.

You then use regular Go communication primitives to send tasks to those
goroutines. Usually, the most simple way is to have each goroutine read "tasks" from a channel and send the results back, like in

type Task struct {
  Data DataTypeToContainRecognitionTask
  Result chan&lt;- DataTypeToContainRecognitionResult
}

func GoroutineLoop(tasks &lt;-chan Task) {
  for task := range tasks {
    task.Result &lt;- recognize(Data)
  }
}

tasks := make(chan Task)
for n := 4; n &gt; 0; n-- {
  go GoroutineLoop(tasks)
}

for {
  res := make(chan DataTypeToContainRecognitionResult)
  tasks &lt;- Task{
    Data: makeRecognitionData(),
    Result: res,
  }
  
  result &lt;- res
  // Do something with the result
}

As to figuring out how much goroutines to start, there exist different
strategies.
The simplest approach is probably to query runtime.NumCPU()
and using this number.

huangapple
  • 本文由 发表于 2017年3月28日 14:28:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/43062111.html
匿名

发表评论

匿名网友

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

确定