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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                在計算機科學中,通信順序過程(communicating sequential processes,CSP)是一種描述并發系統中交互模式的正式語言,它是并發數學理論家族中的一個成員,被稱為過程算法(process algebras),或者說過程計算(process calculate),是基于消息的通道傳遞的數學理論。 CSP模型是上個世紀七十年代提出的,不同于傳統的多線程通過共享內存來通信,CSP講究的是“以通信的方式來共享內存”。用于描述兩個獨立的并發實體通過共享的通訊 channel(管道)進行通信的并發模型。 CSP中channel是第一類對象,它不關注發送消息的實體,而關注與發送消息時使用的channel。 Golang中 channel是被單獨創建并且可以在進程之間傳遞,它的通信模式類似于`boss-worker`模式的,一個實體通過將消息發送到channel 中,然后又監聽這個 channel 的實體處理,兩個實體之間是匿名的,這個就實現實體中間的解耦,其中 channel 是同步的一個消息被發送到 channel 中,最終是一定要被另外的實體消費掉的,在實現原理上其實類似一個阻塞的消息隊列。 Goroutine 是Golang實際并發執行的實體,它底層是使用協程(coroutine)實現并發,coroutine是一種運行在用戶態的用戶線程,類似于greenthread,go底層選擇使用coroutine的出發點是因為, 它具有以下特點: * 用戶空間 避免了內核態和用戶態的切換導致的成本. * 可以由語言和框架層進行調度. * 更小的棧空間允許創建大量的實例. Golang中的Goroutine的特性: Golang內部有三個對象: P對象(processor) 代表上下文(或者可以認為是cpu),M(work thread)代表工作線程,G對象(goroutine). 正常情況下一個CPU對象啟一個工作線程對象,線程去檢查并執行goroutine對象。碰到goroutine對象阻塞的時候,會啟動一個新的工作線程,以充分利用cpu資源。所以有時候線程對象會比處理器對象多很多. 我們用如下圖分別表示P、M、G: [![](https://github.com/KeKe-Li/data-structures-questions/raw/master/src/images/59.jpg)](https://github.com/KeKe-Li/data-structures-questions/blob/master/src/images/59.jpg) * G(Goroutine): 我們所說的協程,為用戶級的輕量級線程,每個Goroutine對象中的sched保存著其上下文信息。 * M(Machine): 對OS內核級線程的封裝,數量對應真實的CPU數(真正干活的對象). * P (Processor): 邏輯處理器,即為G和M的調度對象,用來調度G和M之間的關聯關系,其數量可通過`GOMAXPROCS()`來設置,默認為核心數。 在單核情況下,所有Goroutine運行在同一個線程(M0)中,每一個線程維護一個上下文(P),任何時刻,一個上下文中只有一個Goroutine,其他Goroutine在runqueue中等待。 一個Goroutine運行完自己的時間片后,讓出上下文,自己回到runqueue中(如下圖所示)。 當正在運行的G0阻塞的時候(可以需要IO),會再創建一個線程(M1),P轉到新的線程中去運行。 [![](https://github.com/KeKe-Li/data-structures-questions/raw/master/src/images/60.jpg)](https://github.com/KeKe-Li/data-structures-questions/blob/master/src/images/60.jpg) 當M0返回時,它會嘗試從其他線程中“偷”一個上下文過來,如果沒有偷到,會把Goroutine放到`Global runqueue`中去,然后把自己放入線程緩存中。 上下文會定時檢查`Global runqueue`。 Golang是為并發而生的語言,Go語言是為數不多的在語言層面實現并發的語言;也正是Go語言的并發特性,吸引了全球無數的開發者。 Golang的CSP并發模型,是通過Goroutine和Channel來實現的。 Goroutine 是Go語言中并發的執行單位。有點抽象,其實就是和傳統概念上的”線程“類似,可以理解為”線程“。Channel是Go語言中各個并發結構體(Goroutine)之前的通信機制。通常Channel,是各個Goroutine之間通信的”管道“,有點類似于Linux中的管道。 通信機制channel也很方便,傳數據用`channel <- data`,取數據用`<-channel`。 在通信過程中,傳數據`channel <- data`和取數據`<-channel`必然會成對出現,因為這邊傳,那邊取,兩個goroutine之間才會實現通信。而且不管是傳還是取,肯定阻塞,直到另外的goroutine傳或者取為止。因此GPM的簡要概括即為:事件循環,線程池,工作隊列。
                  <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>

                              哎呀哎呀视频在线观看