2017-10-13 5 views
-1

Je sais que cela est fauxComment assurez-vous que l'ordre d'envoyer un message au canal sont juste

func e6() { 
    c1 := make(chan struct{}, 1) 
    <-c1     
    go func() {   
     c1 <- struct{}{} 
    }() 
} 

ce qui est bon

func e6() { 
    c1 := make(chan struct{}, 1) 
    go func() {   //statement1 
     c1 <- struct{}{} 
    }() 
    <-c1  //statement2 
} 

Puisque nous ne pouvons pas assumer l'ordre du instruction1 et instruction2 dans le bon exemple, que se passe-t-il si le statement2 s'exécute en avant de statement1, et dans ce cas, le bon exemple ressemble juste au mauvais exemple, mais pourquoi est-ce exact? Merci de m'avoir aidé.

Répondre

2

En fait, voici ce qui se passe après que vous avez engendré le goroutine: Soit le goroutine est exécuté en premier et le canal est rempli de sorte que vous pouvez en lire (<-c1) tout de suite. Ou l'instruction read est exécutée en premier, mais comme il n'y a rien à lire sur ce canal, il attend que quelque chose puisse être lu ("It blocks"). Maintenant, le planificateur goroutine entre en action, remarque que l'un des deux blocs de goroutine et "enfin" exécute l'autre goroutine, qui remplit le canal et se termine, rendant le goroutin bloquant le seul restant, ce qui lui permet d'être à nouveau exécuté. Mais maintenant le canal est peuplé, il peut être lu, la valeur du canal est lue dans rien et le goroutine original continue, mettant fin à la fonction.

Veuillez noter que ceci est un peu simplifié, et vous devriez certainement lire sur les goroutines.

+0

Merci beaucoup. –

0

Ceci est faux:

func e6() { 
    c1 := make(chan struct{}, 1) 
    <-c1     
    go func() {   
     c1 <- struct{}{} 
    }() 
} 

, car l'exécution va dans une impasse. En appelant <-c1 dans le thread de la fonction principale, vous bloquez une réception à partir d'un canal ouvert. Receive bloquera jusqu'à ce qu'il reçoive des données de c1 mais aucun processus n'envoie de données dessus. Le goroutine qui est supposé envoyer c1 n'a pas encore démarré depuis que l'exécution du code a été bloquée avant d'atteindre l'instruction go.

Dans la mise en œuvre correcte:

func e6() { 
    c1 := make(chan struct{}, 1) 
    go func() {   //statement1 
     c1 <- struct{}{} 
    }() 
    <-c1  //statement2 
} 

n'a pas d'importance qui se dirige d'abord la déclaration. Si statement1 s'exécute en premier, le goroutine (s'exécutant dans un thread différent) bloque l'envoi c1 (c1 <- struct{}{}) car statement2 n'a pas encore été exécuté et aucun autre processus ne reçoit de données de c1. Cela entraîne l'exécution de l'exécution du goroutine et de l'exécution du goroutin dans le thread de la fonction principale où statement2 s'exécutera (rappelez-vous que l'instruction go ne bloque généralement pas). Cette fois statement2 ne bloquera pas car un autre processus (statement1) est déjà prêt avec les données à envoyer c1. Ainsi, les deux threads continuent à l'achèvement.

Un raisonnement similaire peut être fait pour le cas dans lequel statement2 s'exécute en premier.

+0

Dans la "bonne implémentation", _ "if' instruction1' s'exécute en premier, le goroutine bloque à l'envoi sur "c1" "_. Non, ce n'est pas le cas puisque 'c1' est tamponné. – icza

+0

oh .. n'a pas vu que .. – abhink

+0

'c1' est tampon, mais il n'a aucune donnée, donc si instruction1 s'exécute en premier, le goroutine bloque à envoyer sur c1 –