Sobes.tech
Middle

Чӣ тавр дуруст анҷом додани иҷрои чанд goroutine дар Go?

sobes.tech AI

Ҷавоб аз AI

Меъёри маъмул дарозмуддат вуҷуд дорад:

  • Истифодаи контекст (Context): Равиши тавсияшуда барои бекор кардани амалиётҳо дар сохтори дарахтӣ. Контекст метавонад сигнали бекориро тавассути канал интиқол диҳад.

    package main
    
    import (
        "context"
        "fmt"
        "time"
    )
    
    func worker(ctx context.Context, id int) {
        for {
            select {
            case <-ctx.Done():
                fmt.Printf("Горутин %d ба анҷом мерасад: %v\n", id, ctx.Err())
                return
            default:
                fmt.Printf("Горутин %d кор мекунад...\n", id)
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func main() {
        ctx, cancel := context.WithCancel(context.Background())
    
        go worker(ctx, 1)
        go worker(ctx, 2)
    
        time.Sleep(3 * time.Second)
        cancel() // Истифодаи сигнали бекор
    
        time.Sleep(1 * time.Second) // Вақт додан барои анҷоми горутинҳо
        fmt.Println("Барномаи асосӣ ба анҷом расид.")
    }
    
  • Истифодаи каналҳо: Бо фиристодани сигнали (масалан, сохтори холӣ struct{}) тавассути канал махсус, метавон ба горутина хабар дод, ки вақти анҷом расидааст.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func worker(stopChan <-chan struct{}, id int) {
        for {
            select {
            case <-stopChan:
                fmt.Printf("Горутин %d ба анҷом мерасад тавассути канал\n", id)
                return
            default:
                fmt.Printf("Горутин %d кор мекунад...\n", id)
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func main() {
        stopChan := make(chan struct{})
    
        go worker(stopChan, 1)
        go worker(stopChan, 2)
    
        time.Sleep(3 * time.Second)
        close(stopChan) // Баста кардани канали сигнал медиҳад
    
        time.Sleep(1 * time.Second) // Вақт додан барои анҷоми горутинҳо
        fmt.Println("Барномаи асосӣ ба анҷом расид.")
    }
    
  • Истифодаи sync.WaitGroup (барои интизорӣ, на барои сигнал): WaitGroup барои интизорӣ барои анҷоми гурӯҳи горутинҳо истифода мешавад, аммо худи он механизми боздоштиро пешниҳод намекунад. Онро дар ҳамоҳангӣ бо контекст ё каналҳо аксар вақт истифода мебаранд.

    package main
    
    import (
        "context"
        "fmt"
        "sync"
        "time"
    )
    
    func worker(ctx context.Context, wg *sync.WaitGroup, id int) {
        defer wg.Done() // Кам кардани ҳисобгари `WaitGroup` дар анҷоми горутина
    
        for {
            select {
            case <-ctx.Done():
                fmt.Printf("Горутин %d ба анҷом мерасад\n", id)
                return
            default:
                fmt.Printf("Горутин %d кор мекунад...\n", id)
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func main() {
        ctx, cancel := context.WithCancel(context.Background())
        var wg sync.WaitGroup
    
        numWorkers := 2
        wg.Add(numWorkers) // Инициализатсия кардани `WaitGroup`
    
        for i := 1; i <= numWorkers; i++ {
            go worker(ctx, &wg, i)
        }
    
        time.Sleep(3 * time.Second)
        cancel() // Сигнали бекор
    
        wg.Wait() // интизорӣ барои анҷоми ҳамаи горутинҳо
        fmt.Println("Барномаи асосӣ ба анҷом расид.")
    }
    

Интихоби усул ба ҳолати махсус ва мураккабии муоширати горутинҳо вобаста аст. Контекст одатан барои бекор кардани каскадӣ истифода мешавад.