當填充通道的函數呼叫未嵌入 Goroutine 中時,為什麼會出現死鎖?
當填充通道的函數呼叫未嵌入Goroutine中時,會出現死鎖的原因是因為通道的傳送和接收操作是阻塞的。如果在主Goroutine中呼叫填充通道的函數,並且該函數內部沒有將填充操作放入新的Goroutine中運行,那麼主Goroutine會一直等待通道有足夠的空間來接收數據,而填充操作又無法進行,從而導致死鎖的產生。因此,為了避免死鎖,我們需要在填充通道的操作中使用Goroutine來進行並發執行,以確保填充操作和接收操作可以同時進行。
問題內容
我知道 sync
套件及其 waitgroup
選項,我不想將其用於此測試。我正在測試一種信號量。
所以我有:
package main import ( "fmt" "os" "time" ) func main() { fmt.print("wassap") jobs := make(chan int) processstarted := make(chan struct{}, 1) processcompleted := make(chan struct{}, 1) createjobs(jobs) go func() { worker(jobs, processstarted, processcompleted) }() go func() { sync(processstarted, processcompleted) }() time.sleep(3600 * time.second) fmt.print("\nend of main...") interrupt := make(chan os.signal) <-interrupt } func createjobs(jobs chan<- int) { defer close(jobs) for i := 1; i < 20; i++ { jobs <- i } } func worker(jobs <-chan int, processstarted <-chan struct{}, processcompleted <-chan struct{}) { for { select { case i := <-jobs: fmt.printf("\nfetching job #%d from channel", i) time.sleep(2 * time.second) case <-processstarted: fmt.print("\nprocess started. waiting for it to be completed") <-processcompleted fmt.print("\nprocess completed") } } } func sync(processstarted chan<- struct{}, processcompleted chan<- struct{}) { // acquire semaphore. send signal to channel to indicate that it is busy processstarted <- struct{}{} for i := 1; i < 5; i++ { fmt.printf("\nprocessing %d", i) time.sleep(5 * time.second) } // release semaphore processcompleted <- struct{}{} }
我想要測試的非常簡單:我有一個 createjobs
函數,其唯一目的是將元素添加到通道,在本例中是一個 int 通道。然後我有一個 worker
將從該通道中提取物件並在提取下一個元素之前休眠 2 秒。
現在,還有同步功能。此函數的唯一目的是模擬 worker
執行階段啟動的進程。如果此進程處於活動狀態,則在sync
結束時應停止處理jobs
元素,這就是為什麼我有兩個通道,一個表示進程已啟動,另一個表示進程結束。
運行我的程式碼時出現以下錯誤:
fatal error: all goroutines are asleep - deadlock!
如果我修改 createjobs
的呼叫方式,將其包裝在如下所示的 goroutine 中:
go func() { createJobs(jobs) }()
然後我的程式碼運行正確。
我只是想了解為什麼會發生這種情況。我的意思是: main
例程正在執行,然後它呼叫createjobs
(無換行),因此main
例程應該被阻止,直到此呼叫結束。一旦 createjobs
結束,就表示頻道中有元素了。 main
繼續執行並啟動其他 goroutine worker
和 sync
來完成它們的工作。在 main
結束之前,我只是添加一個睡眠程序,以便為之前創建的 goroutine 提供完成時間。
我不是問這個問題的其他解決方案,我只是想知道當 createjobs
發生在 goroutine 之外時會發生什麼。
解決方法
您將 jobs
宣告為無緩衝通道,然後嘗試將 20 個值同步推入其中。當您呼叫 createjobs(jobs)
時,這將阻止您的主函數。
將第 13 行改為:
jobs := make(chan int, 20)
...將解決僵局。
編輯 - 評論中要求的澄清:
無緩衝通道沒有容量,並且會阻止生產者的執行,直到消費者收到訊息為止。
無緩衝通道的一個很好的類比是管道,在本例中,過程如下所示:
+------------------+ +------------+ +-------------+ | PRODUCER | | PIPE | | CONSUMER | | +---->| +----->| | | createJobs(jobs) | | unbuffered | | worker(...) | | | | channel | | | +------------------+ +------------+ +-------------+
發生死鎖是因為 createjobs(jobs)
被同步調用,而且還沒有消費者在運作。
當在 goroutine 中呼叫函數(producer)時它可以工作,因為基本上插入通道和讀取通道是並行發生的?
是的。如果生產者被非同步調用,它不會阻塞 main()
函數,因此消費者也將有機會被調用。在這種情況下,生產者將一一推送其所有任務,就像工作人員一一消費它們一樣。
以上是當填充通道的函數呼叫未嵌入 Goroutine 中時,為什麼會出現死鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。
