go語言信號量的使用例子


//shared values are passed around on channels


// 信號量.
/*



var sem = make(chan int, MaxOutstanding)

func handle(r *Request) {
    sem <- 1    // Wait for active queue to drain.
    process(r)  // May take a long time.
    <-sem       // Done; enable next request to run.
}

func Serve(queue chan *Request) {
    for {
        req := <-queue
        go handle(req)  // Don't wait for handle to finish.
    }
}


一堆請求requests進入serve中,不停的給req.進行handle操作
每運行一個之前,都用這個公共的變量req來進行維護.信號量滿了就展廳handle新的,
每一個handle玩就會讓信號量+1,可以讓新的東西進來繼續跑.


這個代碼有bug,因為堵塞是在handle里面發生的,所以同時有無窮個請求打過來
的時候,還是會開啟所有的線程,cpu會被無限吃光.




所以就需要下面的讓堵塞發生給for循環上.直接在serve層面堵塞.這樣cpu就只能開
MaxOutstanding這么多的線程了.

func Serve(queue chan *Request) {
    for req := range queue {
        sem <- 1  //因為信號量放這里,堵塞for循環,會讓cpu保證不會無窮耗盡!
        go func() {
            process(req) // Buggy; see explanation below.
            <-sem
        }()
    }
}



//下面處理for循環層面的變量問題,for循環里面的變量是共享內存的.
也就是
上面的代碼for循環中第一次循環體和第二次循環體內容同時跑的時候,他們
操作的是同一個req.這不是我們要的.所以在下面代碼中
go func(req *Request) 進行一次值拷貝,這樣就保證每一次for循環中操作的變量
都唯一了.

func Serve(queue chan *Request) {
    for req := range queue {
        sem <- 1
        go func(req *Request) {
            process(req)
            <-sem
        }(req)
    }
}

//當然下面這個req:=req 是go語言推薦的寫法,確實更加簡練.
//當然也是一次值拷貝.

func Serve(queue chan *Request) {
    for req := range queue {
        req := req // Create new instance of req for the goroutine.
        sem <- 1
        go func() {
            process(req)
            <-sem
        }()
    }
}






*/
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM