<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 9.3\. 同步(Synchronization) ### 9.3.1\. 初始化 程序的初始化在一個獨立的goroutine中執行。在初始化過程中創建的goroutine將在 第一個用于初始化goroutine執行完成后啟動。 如果包p導入了包q,包q的init 初始化函數將在包p的初始化之前執行。 程序的入口函數 main.main 則是在所有的 init 函數執行完成 之后啟動。 在任意init函數中新創建的goroutines,將在所有的init 函數完成后執行。 ### 9.3.2\. Goroutine的創建 用于啟動goroutine的go語句在goroutine之前運行。 例如,下面的程序: ``` var a string; func f() { print(a); } func hello() { a = "hello, world"; go f(); } ``` 調用hello函數,會在某個時刻打印“hello, world”(有可能是在hello函數返回之后)。 ### 9.3.3\. Channel communication 管道通信 用管道通信是兩個goroutines之間同步的主要方法。在管道上執行的發送操作會關聯到該管道的 接收操作,這通常對應goroutines。 管道上的發送操作發生在管道的接收完成之前(happens before)。 例如這個程序: ``` var c = make(chan int, 10) var a string func f() { a = "hello, world"; c <- 0; } func main() { go f(); <-c; print(a); } ``` 可以確保會輸出"hello, world"。因為,a的賦值發生在向管道 c發送數據之前,而管道的發送操作在管道接收完成之前發生。 因此,在print 的時候,a已經被賦值。 從一個unbuffered管道接收數據在向管道發送數據完成之前發送。 下面的是示例程序: ``` var c = make(chan int) var a string func f() { a = "hello, world"; <-c; } func main() { go f(); c <- 0; print(a); } ``` 同樣可以確保輸出“hello, world”。因為,a的賦值在從管道接收數據 前發生,而從管道接收數據操作在向unbuffered 管道發送完成之前發生。所以,在print 的時候,a已經被賦值。 如果用的是緩沖管道(如 c = make(chan int, 1) ),將不能保證輸出 “hello, world”結果(可能會是空字符串, 但肯定不會是他未知的字符串, 或導致程序崩潰)。 ### 9.3.4\. 鎖 包sync實現了兩種類型的鎖: sync.Mutex 和 sync.RWMutex。 對于任意 sync.Mutex 或 sync.RWMutex 變量l。 如果 n &lt; m ,那么第n次 l.Unlock() 調用在第 m次 l.Lock() 調用返回前發生。 例如程序: ``` var l sync.Mutex var a string func f() { a = "hello, world"; l.Unlock(); } func main() { l.Lock(); go f(); l.Lock(); print(a); } ``` 可以確保輸出“hello, world”結果。因為,第一次 l.Unlock() 調用(在f函數中)在第二次 l.Lock() 調用 (在main 函數中)返回之前發生,也就是在 print 函數調用之前發生。 For any call to l.RLock on a sync.RWMutex variable l, there is an n such that the l.RLock happens (returns) after the n'th call to l.Unlock and the matching l.RUnlock happens before the n+1'th call to l.Lock. ### 9.3.5\. Once 包once提供了一個在多個goroutines中進行初始化的方法。多個goroutines可以 通過 once.Do(f) 方式調用f函數。 但是,f函數 只會被執行一次,其他的調用將被阻塞直到唯一執行的f()返回。 once.Do(f) 中唯一執行的f()發生在所有的 once.Do(f) 返回之前。 有代碼: ``` var a string func setup() { a = "hello, world"; } func doprint() { once.Do(setup); print(a); } func twoprint() { go doprint(); go doprint(); } ``` 調用twoprint會輸出“hello, world”兩次。第一次twoprint 函數會運行setup唯一一次。
                  <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>

                              哎呀哎呀视频在线观看