我正在嘗試更好地了解 GO 中的頻道。
希望 5 個例程始終運行。在第一個例程的特定時間,我想嘗試開始另一個例程。假設 5 個例程已經在運行,我想將下一個例程排隊,并在其他例程之一完成后立即運行它。
我的邏輯是呼叫將訊息傳遞給 spawner,檢查是否有 5 個行程已經在運行,如果是,請繼續等待,直到沒有,然后啟動。據我所知,是p.complete <- struct{}{}沒有按預期作業并洗掉一個程序。它在 go 例程之外運行良好。
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
type ProcessManager struct {
spawner chan struct{}
complete chan struct{}
process int
}
func NewProcessManager() *ProcessManager {
return &ProcessManager{
spawner: make(chan struct{}),
complete: make(chan struct{}),
process: 0,
}
}
func (p *ProcessManager) Run(limit int) {
for {
select {
case <-p.spawner:
for {
if p.process <= limit {
fmt.Println("breaking for new process")
break
}
time.Sleep(time.Second * 10)
}
p.process
go func() {
fmt.Println(" Starting goroutine")
p.spawner <- struct{}{}
time.Sleep(time.Second * 2)
fmt.Println("- Stopping goroutine")
p.complete <- struct{}{}
}()
case <-p.complete:
fmt.Println("complete")
p.process--
}
}
}
func main() {
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
pm := NewProcessManager()
go pm.Run(5)
pm.spawner <- struct{}{}
<-interruptChannel
}
uj5u.com熱心網友回復:
設法通過切換程序來解決這個問題 process: make(chan int, 4)
然后我只是用它來阻塞而不是 for 回圈p.process <- 1
,然后用它來將例程標記為已完成<-p.process
通道 (4) 的長度將決定在任何給定時間允許運行的最大處理數。我在下面提供的更新測驗:
func NewProcessManager() *ProcessManager {
return &ProcessManager{
spawner: make(chan struct{}),
complete: make(chan struct{}),
process: make(chan int, 4),
}
}
func (p *ProcessManager) Run() {
for {
select {
case <-p.spawner:
p.process <- 1
go func() {
fmt.Println(" Starting goroutine")
// do stuff before starting next routine
p.spawner <- struct{}{}
// do stuff rest of stuff
fmt.Println("- Stopping goroutine")
<-p.process
}()
}
}
uj5u.com熱心網友回復:
ProcessManager在我看來,整個目的是序列化對元資料的訪問,以跟蹤正在運行的行程。因此,它按順序運行。
case <-p.spawner:
for {
if p.process <= limit {
fmt.Println("breaking for new process")
break
}
time.Sleep(time.Second * 10)
}
在這部分代碼中,goroutine 處于休眠狀態。睡眠時,select 陳述句中的完整案例無法運行。
回想一下無緩沖通道的以下屬性:
默認情況下,發送和接收阻塞,直到對方準備好。
因為通道是無緩沖的,所以這行代碼必須阻塞,直到觸發完整的案例:
p.complete <- struct{}{}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/409663.html
標籤:
