Чӣ тавр дуруст анҷом додани иҷрои чанд 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("Барномаи асосӣ ба анҷом расид.") }
Интихоби усул ба ҳолати махсус ва мураккабии муоширати горутинҳо вобаста аст. Контекст одатан барои бекор кардани каскадӣ истифода мешавад.