請轉到最后一部分并告訴我您將如何解決此問題。今天早上我開始使用來自 Python 的 Go。我想從 Go 調用一個閉源可執行文件多次,有一點并發,有不同的命令行參數。我生成的代碼運行良好,但我想得到您的意見以改進它。由于我處于早期學習階段,我還將解釋我的工作流程。為了簡單起見,這里假設這個“外部閉源程序”是zenity一個 Linux 命令行工具,可以從命令行顯示圖形消息框。從 Go 調用可執行文件所以,在 Go 中,我會這樣:package mainimport "os/exec"func main() { cmd := exec.Command("zenity", "--info", "--text='Hello World'") cmd.Run()}這應該工作得恰到好處。請注意,這.Run()是一個功能等價于.Start()后跟.Wait()。這很好,但是如果我只想執行一次這個程序,那么整個編程的東西就不值得了。所以讓我們多次這樣做。多次調用可執行文件現在我有了這個工作,我想用自定義命令行參數多次調用我的程序(這里只是i為了簡單起見)。package main import ( "os/exec" "strconv")func main() { NumEl := 8 // Number of times the external program is called for i:=0; i<NumEl; i++ { cmd := exec.Command("zenity", "--info", "--text='Hello from iteration n." + strconv.Itoa(i) + "'") cmd.Run() }}好的,我們做到了!但是還是看不出Go over Python的優勢……這段代碼其實是串行執行的。我有一個多核 CPU,我想利用它。所以讓我們用 goroutines 添加一些并發性。Goroutines,或一種使我的程序并行的方法a) 第一次嘗試:只需在任何地方添加“go”讓我們重寫我們的代碼,使調用和重用更容易,并添加著名的go關鍵字:package mainimport ( "os/exec" "strconv")沒有什么!問題是什么?所有的 goroutine 都被一次性執行。我真的不知道為什么不執行 zenity 但 AFAIK,Go 程序在 zenity 外部程序甚至可以初始化之前就退出了。這通過使用time.Sleep: 等待幾秒鐘就足以讓 zenity 的 8 實例自行啟動。我不知道這是否可以被視為一個錯誤。更糟糕的是,我真正想要調用的真正程序需要一段時間才能執行。如果我在我的 4 核 CPU 上并行執行這個程序的 8 個實例,它會浪費一些時間做很多上下文切換……我不知道普通 Go協程的行為,但exec.Command 會在 8 個不同的線程中啟動 zenity 8 次. 更糟糕的是,我想執行這個程序超過 100,000 次。在 goroutine 中一次完成所有這些工作根本沒有效率。不過,我想利用我的 4 核 CPU!b) 第二次嘗試:使用 goroutines 池在線資源傾向于推薦sync.WaitGroup用于此類工作。這種方法的問題在于,您基本上是在處理成批的 goroutine:如果我創建了 4 個成員的 WaitGroup,則 Go 程序將等待所有4 個外部程序完成,然后再調用新的 4 個程序批次。這效率不高:CPU 又一次被浪費了。這看起來很丑。頻道并非用于此目的:我正在利用副作用。我喜歡這個概念,defer但我討厭必須聲明一個函數(甚至是一個 lambda)來從我創建的虛擬通道中彈出一個值。哦,當然,使用虛擬通道本身就是丑陋的。完畢。我的問題你知道任何其他適當的方法來限制一次執行的 goroutines 的數量嗎?我不是指線程;Go 如何在內部管理 goroutines 并不相關。我的意思是限制一次啟動的 goroutine 的數量:exec.Command每次調用時都會創建一個新線程,所以我應該控制它被調用的次數。你覺得這段代碼好嗎?您知道在這種情況下如何避免使用虛擬通道嗎?我無法說服自己這樣的虛擬頻道是要走的路。
- 3 回答
- 0 關注
- 208 瀏覽
添加回答
舉報
0/150
提交
取消