2015-02-24 5 views
2

TL; DR принимает и соединяет две отдельные SETS соединений. Хотите сделать это с RPC одновременно.Проблемы с Go Routines и его параллелизм

Я пытаюсь создать полураспределенную систему на своем компьютере. Часть кода, над которым я сейчас работаю, - это что-то вроде брокерского узла, другими словами, он всегда принимает клиентские соединения из порта. Он также постоянно принимает соединения на заднем конце узла из другого порта. Я пытаюсь найти способ одновременно слушать и то, и другое. Я использую RPC и способ, которым я пытался делать это так: 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} 
} 

Одновременные функции:

// 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  
} 
} 

Вопрос заключается в том, что она служит не первый узел, пока вторая идет вперед. Я не понимаю, почему. Также кажется, что во времени может произойти только одно соединение, но я думал, что RPC обслуживается на другом порту (таким образом, не блокируя его). Любая помощь очень ценится.

Я пробовал следующее this tutorial, но я обнаружил, что это обстоятельство слишком отличается, его также использует другая версия Go. Я использую два типа узлов/соединений, где тип A должен быть подан через брокера типа B.

+1

Если я не ошибаюсь, goroutine, как волокна, и выполняет какую-то совместную многозадачность. Мне кажется, что ваша текущая реализация блокирует себя. Надеюсь, что этот комментарий дает подсказку --- dunno семантики Go достаточно, чтобы рассказать больше на этом этапе. –

+0

Вы правы: goroutines делают совместную многопоточность на абстрактном уровне над потоками ОС. Другими словами, каждый поток ОС может, по-видимому, одновременно запускать множество goroutines. Время выполнения Go делает это по времени - разрезает goroutines на поток. –

+0

Спасибо за подтверждение. Затем я думаю, что вызов 'Accept' блокирует поток, поэтому все goroutines. Необходимо либо выполнить исполнение, либо изменить фактические потоки или каналы. –

ответ

1

В конце концов, я думаю, что этот вопрос, что я пытался проход в слушателях к Go рутине , при этом каждая из которых работает с зависимостью от основной нити. Рабочее решение оказалось таким простым:

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 :-) 
    } 
}