>백엔드 개발 >Golang >채널을 채우는 함수 호출이 고루틴에 포함되지 않은 경우 교착 상태가 발생하는 이유는 무엇입니까?

채널을 채우는 함수 호출이 고루틴에 포함되지 않은 경우 교착 상태가 발생하는 이유는 무엇입니까?

王林
王林앞으로
2024-02-10 12:00:10760검색

当填充通道的函数调用未嵌入 Goroutine 中时,为什么会出现死锁?

채널을 채우는 함수 호출이 고루틴에 포함되지 않은 경우 교착 상태가 발생하는 이유는 채널의 전송 및 수신 작업이 차단되기 때문입니다. 채널을 채우는 함수가 메인 고루틴에서 호출되고 채우기 작업이 함수 내부에서 실행되는 새 고루틴에 들어가지 않으면, 메인 고루틴은 채널이 데이터를 받을 수 있는 충분한 공간을 가질 때까지 기다립니다. 채우기 작업을 수행할 수 없어 교착 상태가 발생합니다. 따라서 교착상태를 피하기 위해서는 채우기 작업과 수신 작업이 동시에 수행될 수 있도록 채널을 채우는 작업에서 동시 실행을 위해 고루틴을 사용해야 합니다.

질문 내용

저는 sync 包及其 waitgroup 옵션에 대해 알고 있는데 이 테스트에 사용하고 싶지 않습니다. 세마포어를 테스트 중입니다.

그래서 나는:

으아아아

내가 테스트하고 싶은 것은 매우 간단합니다. 해당 채널에서 개체를 추출하고 다음 요소를 추출하기 전에 2초 동안 대기하는 createjobs 函数,其唯一目的是将元素添加到通道,在本例中是一个 int 通道。然后我有一个 worker가 있습니다.

이제 동기화 기능도 있습니다. 이 기능의 유일한 목적은 worker 运行时启动的进程。如果此进程处于活动状态,则在 sync 结束时应停止处理 jobs 요소를 시뮬레이션하는 것입니다. 그래서 두 개의 채널이 있습니다. 하나는 프로세스가 시작되었음을 나타내고 다른 하나는 프로세스가 종료되었음을 나타냅니다.

코드를 실행할 때 다음 오류가 발생합니다.

으아아아

createjobs 호출 방식을 수정하면 다음과 같이 고루틴으로 래핑합니다.

으아아아

그러면 내 코드가 올바르게 실행됩니다.

왜 이런 일이 발생하는지 알고 싶습니다. 내 말은: main 루틴이 실행 중이고 main 例程正在执行,然后它调用 createjobs (无换行),因此 main 例程应该被阻止,直到此调用结束。一旦 createjobs 结束,就说明通道中有元素了。 main 继续执行并启动其他 goroutine workersync 来完成它们的工作。在 main(개행 없이)을 호출하므로 main 루틴은 이 호출이 끝날 때까지 차단되어야 한다는 것입니다.

가 끝나면 채널에 요소가 있다는 의미입니다. main은 실행을 계속하고 다른 goroutine workersync를 시작하여 작업을 완료합니다. main이 끝나기 전에 이전에 생성된 고루틴이 완료될 시간을 주기 위해 슬리퍼를 추가하기만 하면 됩니다.

createjobs 发生在 goroutine 之外时会发生什么。

解决方法

您将 jobs 声明为无缓冲通道,然后尝试将 20 个值同步推入其中。当您调用 createjobs(jobs)저는 이 문제에 대한 다른 해결책을 요구하는 것이 아닙니다. 단지 고루틴 외부에서

문제가 발생하면 어떤 일이 발생하는지 알고 싶을 뿐입니다.

해결 방법

작업을 버퍼링되지 않은 채널로 선언한 다음 20개의 값을 동기식으로 푸시해 봅니다. 이렇게 하면

에 전화할 때 기본 기능이 차단됩니다. 13행을 다음으로 변경하세요.

으아아아

...교착상태를 해결하겠습니다.

EDIT - 댓글에서 설명이 요청되었습니다:

createjobs(jobs)

버퍼링되지 않은 채널에는 용량이 없으며 소비자가 메시지를 받을 때까지 생산자의 실행을 차단합니다.

버퍼되지 않은 채널에 대한 좋은 비유는 파이프입니다. 이 경우 프로세스는 다음과 같습니다. 으아아아

교착 상태는

가 동기적으로 호출되고 아직 실행 중인 소비자가 없기 때문에 발생합니다. main()

기본적으로 채널 삽입과 채널 읽기가 병렬로 일어나기 때문에 고루틴에서 함수(🎜producer🎜)를 호출하면 작동하나요? 🎜 🎜네. 생산자가 비동기적으로 호출되면 🎜 기능이 차단되지 않으므로 소비자도 호출될 기회가 있습니다. 이 경우 생산자는 작업자가 작업을 하나씩 소비하는 것처럼 모든 작업을 하나씩 푸시합니다. 🎜

위 내용은 채널을 채우는 함수 호출이 고루틴에 포함되지 않은 경우 교착 상태가 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제