在这个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/

10-16 07:04