在这个ZeroMQ example中,
// Multithreaded Hello World server.
// Uses Goroutines. We could also use channels (a native form of
// inproc), but I stuck to the example.
//
// Author: Brendan Mc.
// Requires: http://github.com/alecthomas/gozmq
package main
import (
"fmt"
zmq "github.com/alecthomas/gozmq"
"time"
)
func main() {
// Launch pool of worker threads
for i := 0; i != 5; i = i + 1 {
go worker()
}
// Prepare our context and sockets
context, _ := zmq.NewContext()
defer context.Close()
// Socket to talk to clients
clients, _ := context.NewSocket(zmq.ROUTER)
defer clients.Close()
clients.Bind("tcp://*:5555")
// Socket to talk to workers
workers, _ := context.NewSocket(zmq.DEALER)
defer workers.Close()
workers.Bind("ipc://workers.ipc")
// connect work threads to client threads via a queue
zmq.Device(zmq.QUEUE, clients, workers)
}
func worker() {
context, _ := zmq.NewContext()
defer context.Close()
// Socket to talk to dispatcher
receiver, _ := context.NewSocket(zmq.REP)
defer receiver.Close()
receiver.Connect("ipc://workers.ipc")
for true {
received, _ := receiver.Recv(0)
fmt.Printf("Received request [%s]\n", received)
// Do some 'work'
time.Sleep(time.Second)
// Send reply back to client
receiver.Send([]byte("World"), 0)
}
}
每个goroutine都有自己的ZeroMQ Context
。但是,在ZeroMQ guide中,它表示以下内容:我知道goroutines不是线程。
相反,它们生活在线程中。但是我也读过,goroutines之间可能有一个共享对象。
那么,为什么在goroutine之间不共享上下文?
我认为它会占用更少的空间,因为其中包含套接字的上下文可能会很大。
但是,即使不是那么耗费,为什么在此示例中根本不共享上下文?
最佳答案
您可以在Goroutines之间绝对共享对象,只要这些对象是线程安全的即可。您正在使用的Go ZeroMQ绑定(bind)明确地是非线程安全的。尽管单个Goroutine可能不对应于单个OS线程,但是无法保证您生成的Goroutines将驻留在同一OS线程上。它们的生命周期由Go运行时动态管理。
您可以使用channels同步访问权限,也可以使用mutexes在多个Goroutine之间“共享”您的ZeroMQ套接字,在Goroutine访问套接字时您可以在其中锁定对套接字的访问。
关于multithreading - 为什么未在所有goroutine之间共享ZeroMQ上下文?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42034641/