[英]Why does the goroutine not block for time.Sleep(duration)
我運行的程序:
package main
import (
"flag"
"fmt"
"os"
"os/signal"
"time"
)
var sleepSeconds string
var timeToSleep time.Duration
func init() {
flag.StringVar(&sleepSeconds, "sleep", "1s", "-sleep \"3s\"")
}
func main() {
startTime := time.Now()
fmt.Println("Start Time: ", startTime)
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt)
// Block until a signal is received.
flag.Parse()
timeToSleep, err := time.ParseDuration(sleepSeconds)
if err != nil {
fmt.Println("unable to parse the duration: ", err)
return
}
fmt.Println("Time to Sleep: ", timeToSleep)
myChan := make(chan string)
go one(myChan)
go two(myChan)
go three(myChan)
var s os.Signal
fmt.Println("Signal is, ", s)
go func() {
s = <-c
fmt.Println("After receiving Signal is, ", s)
}()
i := 0
for {
i++
generatedString := fmt.Sprintf("%d", i)
fmt.Println("Generating... ", generatedString)
myChan <- generatedString
// time.Sleep(timeToSleep)
fmt.Println("Length of Channel: ", len(myChan))
if s != nil {
break
}
}
fmt.Println("Total time the program ran for: ", time.Since(startTime))
}
func one(dataCh chan string) {
for val := range dataCh {
fmt.Printf("Value received in func one: %s\n", val)
time.Sleep(timeToSleep)
}
}
func two(dataCh chan string) {
for val := range dataCh {
fmt.Printf("Value received in func two: %s\n", val)
time.Sleep(timeToSleep)
}
}
func three(dataCh chan string) {
for val := range dataCh {
fmt.Printf("Value received in func three: %s\n", val)
time.Sleep(timeToSleep)
}
}
當我使用以下標志(5s)運行此程序時
./ichan -sleep "5s" > data.txt
輸出令人費解,因為我看到程序只運行了2.31606525s
但所有 3 個 goroutine 都應該被阻塞至少 5 秒。 data.txt 是此存儲庫的一部分以供參考,代碼也可在同一存儲庫中找到。
我的問題是:函數one
、 two
和three
中的 time.Sleep() 應該被阻塞,直到睡眠持續時間,然后從通道中消耗字符串,但觀察到睡眠對 goroutines 沒有任何影響.
timeToSleep, err :=
創建一個名為 timeToSleep 的新局部變量,該變量獨立於同名的包級別變量,因此包級別變量始終為零。
您似乎錯過了本機持續時間標志類型: https : //pkg.go.dev/flag#DurationVar
func init() {
flag.DurationVar(&timeToSleep, "sleep", 1*time.Second, `-sleep "3s"`)
}
同一程序的工作副本
package main
import (
"flag"
"fmt"
"os"
"os/signal"
"time"
)
var sleepSeconds string
var timeToSleep time.Duration
var err error
func init() {
flag.StringVar(&sleepSeconds, "sleep", "1s", "-sleep \"3s\"")
}
func main() {
startTime := time.Now()
fmt.Println("Start Time: ", startTime)
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt)
// Block until a signal is received.
flag.Parse()
timeToSleep, err = time.ParseDuration(sleepSeconds)
if err != nil {
fmt.Println("unable to parse the duration: ", err)
return
}
fmt.Println("Time to Sleep: ", timeToSleep)
myChan := make(chan string)
go one(myChan)
go two(myChan)
go three(myChan)
var s os.Signal
fmt.Println("Signal is, ", s)
go func() {
s = <-c
fmt.Println("After receiving Signal is, ", s)
}()
i := 0
for {
i++
generatedString := fmt.Sprintf("%d", i)
fmt.Println("Generating... ", generatedString)
myChan <- generatedString
// time.Sleep(timeToSleep)
fmt.Println("Length of Channel: ", len(myChan))
if s != nil {
break
}
}
fmt.Println("Total time the program ran for: ", time.Since(startTime))
}
func one(dataCh chan string) {
for val := range dataCh {
fmt.Printf("Value received in func one: %s\n", val)
time.Sleep(timeToSleep)
}
}
func two(dataCh chan string) {
for val := range dataCh {
fmt.Printf("Value received in func two: %s\n", val)
time.Sleep(timeToSleep)
}
}
func three(dataCh chan string) {
for val := range dataCh {
fmt.Printf("Value received in func three: %s\n", val)
time.Sleep(timeToSleep)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.