> 백엔드 개발 > Golang > 버퍼링된 채널을 세마포어로 사용할 때 모든 고루틴이 완료되도록 하려면 어떻게 해야 합니까?

버퍼링된 채널을 세마포어로 사용할 때 모든 고루틴이 완료되도록 하려면 어떻게 해야 합니까?

Susan Sarandon
풀어 주다: 2024-12-02 00:54:13
원래의
566명이 탐색했습니다.

How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?

WaitGroup을 사용하여 버퍼링된 채널 비어 있음

동시 프로그래밍에서는 동시에 실행되는 고루틴 수를 제어해야 하는 경우가 많습니다. 일반적인 접근 방식은 버퍼링된 채널을 세마포어로 사용하는 것입니다. 그러나 이 접근 방식의 제한 사항에 유의하는 것이 중요합니다.

다음 예를 고려하세요.

ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 sem := make(chan struct{}, 2)
for _, i := range ints {
  sem<- struct{}{}
  go func(id int, sem chan struct{}) {
    // do something
    <-sem
  }(i, sem)
}
로그인 후 복사

이 코드는 크기 2의 버퍼링된 채널(sem)을 사용하여 동시 연결 수를 제한합니다. 그러나 문제가 있습니다. 마지막 몇 개의 고루틴이 작업을 완료하기 전에 프로그램이 종료될 수 있습니다. 이는 프로그램이 더 많은 고루틴을 디스패치하는 동안에도 처리 중 언제든지 버퍼링된 채널이 비워질 수 있기 때문입니다.

버퍼링된 채널이 배수될 때까지 기다리려면 채널 자체에 의존할 수 없습니다. 대신에 sync.WaitGroup을 사용하여 처리되지 않은 고루틴 수를 추적할 수 있습니다.

sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for _, i := range ints {
  wg.Add(1)
  sem<- struct{}{}
  go func(id int) {
    defer wg.Done()
    // do something
    <-sem
  }(i)
}
wg.Wait()
로그인 후 복사

이 수정된 코드에서는 wg.Add(1)를 사용하여 각 고루틴을 디스패치하기 전에 대기 그룹을 증가시킵니다. defer wg.Done() 문은 고루틴이 작업을 완료할 때 대기 그룹을 감소시킵니다. 마지막으로 wg.Wait()는 대기 그룹이 0에 도달할 때까지 차단하여 모든 고루틴의 실행이 완료되었는지 확인합니다. 이 접근 방식을 사용하면 채널이 소모될 때까지 기다릴 수 있으며 프로그램이 조기에 종료되지 않도록 할 수 있습니다.

위 내용은 버퍼링된 채널을 세마포어로 사용할 때 모든 고루틴이 완료되도록 하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿