douhui8163 2015-02-24 00:09
浏览 55
已采纳

Go例程及其并发问题

TL;DR accepting and connecting two separate SETS of connections. Want to do it with RPC concurrently.

I'm attempting to create semi distributed system on my computer. The piece of the code I'm working on right now is something like a broker node, in other words it is always accepting client connections from a port. Its also constantly accepting back end node connections from a different port. I'm trying to find a way to concurrently listen for both, and serve both. I'm using RPC and the way I tried doing it is this: Main:

func main(){  
 ...  
 rpc.Register(myInterface)  
 l, err := net.Listen("tcp", client_port)  
 if err != nil {...}  
 go handleClients(l)  
 node_l, err := net.Listen("tcp", node_port)  
 if err != nil{...}   
 go setUpIncomingNodes(node_l, chan)  
 for{// add nodes to a list from chan} 
}

Concurrent functions:

// Adds clients to be connected
func handleClients(listener net.Listener){
 for{
  conn, err :=listener.Accept()
  if err != nil{...}
  // Starts up a blocking (on that thread) RPC connection
  go rpc.serveConn(conn)
 }
}
func setUpIncomingNodes(node_listener net.Listener, incoming_nodes chan<- net.Conn){
 for{
  conn, err := node_listener.Accept()
  if err != nil{...}
  incoming_nodes <- conn     
 }
}

The issue is that it doesn't serve the first node, until the second comes along. I can't understand why. Also it seems that only one connection can happen at time, but I thought RPC served on a different port (thus not blocking it). Any help is super appreciated.

I tried following this tutorial but I found the circumstance too different, its also using a different version of Go. I use two types of nodes/connections where Type A needs to be served through the broker to Type B.

  • 写回答

1条回答 默认 最新

  • douzhang1115 2015-02-24 16:57
    关注

    In the end, I think the issue was that I was attempting to pass in listeners to the Go routine, thus having each go routine having a dependancy with the main thread. The working solution ended up being as simple as this:

    func main(){
     ...
     node_ip_port := "127.0.0.1:9000"
     client_ip_port := "127.0.0.1:1000"
     nodeChan := make(chan net.Conn, 20)
    
     go func(ip_port string, nodeChan chan<- net.Conn) {
        l, err := net.Listen("tcp", node_ip)
        if err != nil {
            log.Fatal("Had an error connecting to node", err)
        }
        for {
            conn, _ := l.Accept()
            kvChan <- conn
        }
      }(node_ip_port, nodeChan)
    
     go func(ip_port string) {
        l, err := net.Listen("tcp", ip_port)
        if err != nil {
            log.Fatal("Had an error connecting to client", err)
        }
        for {
            conn, _ := l.Accept()
            go rpc.ServeConn(conn)
        }
      }(client_ip_port)
      // List of connected nodes
      nodeList := list.New()
      for {
        node := <-nodeChan
        nodeList.PushBack(node)
        // My RPC functions use the nodes in this list to serve :-)
      }
     }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line