Maison  >  Article  >  développement back-end  >  Comment fermer la coroutine Golang

Comment fermer la coroutine Golang

尚
original
2019-12-28 10:14:587376parcourir

Comment fermer la coroutine Golang

1. Passez le signal de sortie via le canal

Le canal est un type de données de base. Il a 3 états de base : nul, ouvert. , fermé.

Partagez des données via Channel au lieu de partager des données via la mémoire partagée. Le processus principal peut envoyer un signal d'arrêt à n'importe quelle goroutine via le canal, comme ce qui suit :

func run(done chan int) {
        for {
                select {
                case <-done:
                        fmt.Println("exiting...")
                        done <- 1
                        break
                default:
                }
 
                time.Sleep(time.Second * 1)
                fmt.Println("do something")
        }
}
 
func main() {
        c := make(chan int)
 
        go run(c)
 
        fmt.Println("wait")
        time.Sleep(time.Second * 5)
 
        c <- 1
        <-c
 
        fmt.Println("main exited")
}

2 Utiliser waitgroup

Habituellement, nous utilisons waitgroup comme suivant. :

1. Créez une instance de Waitgroup, en supposant que nous l'appelons wg

2 Lorsque chaque goroutine démarre, appelez wg.Add(1). Cette opération peut être effectuée dans Appelé avant goroutine. démarre, il peut également être appelé dans goroutine. Bien sûr, vous pouvez également appeler wg.Add(n)

avant de créer n goroutines 3. Une fois que chaque goroutine a terminé sa tâche, appelez wg.Done()

4. La goroutine appelle wg.Wait(), qui se bloque avant que toutes les goroutines qui ont exécuté wg.Add(1) n'aient appelé wg.Done(). Elle reviendra après que toutes les goroutines aient appelé wg.Done().

Exemple :

type Service struct {
        // Other things
 
        ch        chan bool
        waitGroup *sync.WaitGroup
}
 
func NewService() *Service {
	s := &Service{
                // Init Other things
                ch:        make(chan bool),
                waitGroup: &sync.WaitGroup{},
	}
 
	return s
}
 
func (s *Service) Stop() {
        close(s.ch)
        s.waitGroup.Wait()
}
 
func (s *Service) Serve() {
        s.waitGroup.Add(1)
        defer s.waitGroup.Done()
 
        for {
                select {
                case <-s.ch:
                        fmt.Println("stopping...")
                        return
                default:
                }
                s.waitGroup.Add(1)
                go s.anotherServer()
	}
}
func (s *Service) anotherServer() {
        defer s.waitGroup.Done()
        for {
                select {
                case <-s.ch:
                        fmt.Println("stopping...")
                        return
                default:
                }
 
                // Do something
        }
}
 
func main() {
 
        service := NewService()
        go service.Serve()
 
        // Handle SIGINT and SIGTERM.
        ch := make(chan os.Signal)
        signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
        fmt.Println(<-ch)
 
        // Stop the service gracefully.
        service.Stop()
}

Pour plus de connaissances sur le golang, veuillez faire attention à la colonne tutoriel golang.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn