<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 一、概念 * go中channel實現了同步,確保并發安全,同時也提供了鎖的操作方式 * go中sync包提供了鎖相關的支持 * Mutex:以加鎖方式解決并發安全問題 * sync.WaitGroup:用來等待一組子協程的結束,需要設置等待的個數,每個子協程結束后要調用Done(),最后在主協程中Wait()即可。 Add():添加計數 Done():操作結束時調用,計數減1 Wait():等待所有操作結束 ## 二、加鎖與不加鎖的區別 #### 不加鎖 ~~~ package main import ( "time" "fmt" ) //賬戶 type Account struct { money int } //模擬安全校驗的 func (a *Account) Check() { time.Sleep(time.Second) } //設置余額 func (a *Account) SetAccount(n int) { a.money += n } //查詢余額 func (a *Account) GetAccount() int { return a.money } //買東西 func (a *Account) Buy(n int) { if a.money > n { a.Check() a.money -= n } } func main() { var account Account account.SetAccount(100) //開2個協程買東西 go account.Buy(60) go account.Buy(50) time.Sleep(2 * time.Second) fmt.Println(account.GetAccount()) } ~~~ 運行結果 -10 #### 加鎖 ~~~ package main import ( "time" "fmt" "sync" ) //賬戶 type Account struct { money int flag sync.Mutex //設置鎖 } //模擬安全校驗的 func (a *Account) Check() { time.Sleep(time.Second) } //設置余額 func (a *Account) SetAccount(n int) { a.money += n } //查詢余額 func (a *Account) GetAccount() int { return a.money } //買東西 func (a *Account) Buy(n int) { //加鎖 a.flag.Lock() if a.money > n { a.Check() a.money -= n } //解鎖 a.flag.Unlock() } func main() { var account Account account.SetAccount(100) //開2個協程買東西 go account.Buy(60) go account.Buy(50) time.Sleep(2 * time.Second) fmt.Println(account.GetAccount()) } ~~~ 執行結果: 50 ## 三、如果主協程中沒有內容子協程就不會去執行 #### 主協程沒有內容 ~~~ package main import ( "fmt" ) func main() { go func() { fmt.Println("子協程1") }() go func() { fmt.Println("子協程2") }() } ~~~ 運行結果: #### 解決原理 ~~~ package main import ( "fmt" ) func main() { m1 := make(chan int) // 子協程活動個數 count :=2 go func() { fmt.Println("子協程1") // 協程1結束,發出信號 m1 <- 1 }() go func() { fmt.Println("子協程2") // 協程2結束,發出信號 m1 <- 1 }() for range m1{ //讀一個數據 count-1 count -- if count ==0{ close(m1) } } } ~~~ 執行結果: 子協程2運行 子協程1運行 #### 使用 sync.WaitGroup 解決 ~~~ package main import ( "sync" "fmt" ) func main() { //聲明等待組 var wg sync.WaitGroup wg.Add(2) go func() { fmt.Println("子協程1運行") wg.Done() }() go func() { fmt.Println("子協程2運行") wg.Done() }() wg.Wait() } ~~~ 執行結果: 子協程2運行 子協程1運行
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看