Go學習

Go語言是Google出了一個語言,基本概念我就不介紹了, GO語言從原生上支持高併發,並提供了簡單的調用方式,咱們就重點研究一下它的高併發html

在介紹高併發以前,咱們須要瞭解一下咱們如今的進程和線程,以及用戶態和內核態。
一個可運行程序在磁盤上的時候,是一個靜態的,當運行被加載到內存的時候,就是一個進程,其內存被分割爲幾個區域,關於進程的概念能夠參考我寫的關於Java的一篇博客。
嚴格來講,進程是不能運行的,操做系統調度的最小單元是線程,因此當程序被加載到內存的時候,默認的就有一個線程,這個線程被稱爲主線程。
主線程能夠建立多個線程,在通常的操做系統中,當你運行在用戶態的程序準備建立一個線程的時候,程序會中斷,由用戶態轉到內核態,在內核態建立一個線程,建立成功後,再轉到用戶態,建立的這個線程對用戶態和內核態是可見的,操做系統的調度也是基於這些對於內核態可見的線程。 node

可是用戶態的線程和內核態的線程並不老是1:1的關係,這裏用戶態線程和內核態線程的對應關係能夠有如下兩種:
1:1模型 即一個用戶態線程對應一個內核態線程,這種模式最多見,能夠利用多核的優點,可是線程的建立和切換會比較慢。
N:1模型:即多個用戶態線程對應一個內核態線程,注意這裏其實已經有協程的概念了, 這裏N個用戶態線程對與內核態來講並不知道,全部的用戶態線程都對應到了一個內核態上。這種模式下,用戶級線程之間的切換能夠很快,可是不能很好的利用多核的優點。golang

線程的建立是一個很耗時的過程,要爲線程準備資源,要用戶態和內核態的切換,Apache服務器就是這樣的,因此若是Go採用這種模式,那也不會有高併發和高性能,這裏GO之因此敢稱高併發和高性能,是由於他有了協程的概念。
關於進程, 線程, 協程的關係:http://www.mamicode.com/info-detail-861488.html
這裏咱們暫時把協程稱爲輕量級線程,是由於
1. 建立的時候, 不通過核心態,直接在用戶態建立,減小了系統調用。
2. 運行的時候,不受核心態管理,包括線程的上下文切換,服務器

Go中的線程模型採用 M:N 的方式。簡單說就是程序啓動時設定啓用幾個線程,這些線程就是普通的操做系統線程,每一個線程運行一個scheduler(由golang的runtime提供),開發人員能夠在用戶態內建立了多個協程,這些協程會被放到每一個scheduler的Task列表內,程序運行時每一個scheduler維護本身的task列表(goroutine),並進行調度。調度方式跟nodejs相似,遇到I/O時,把時間片讓出來給其它任務使用。既要利用多核cpu系統的特性,同時還要加強上下文切換的速度。缺點就是,這會使得調度器的實現變得複雜。併發

Go之因此敢稱高併發,是由於它使用了協程的概念,協程的建立是不通過內核態,直接在用戶態建立,建立的成本變得極小,所以能夠大量建立,另外,因爲這些協程,並不受核心態的調度,因此要運行他們,就須要再有一個調度器來調度這些協程,因此GO中有一個很重要的概念就是調度器(scheduler),最後的運行就是這樣樣子: 操做系統調度線程, 該線程上的scheduler就開始運行,而scheduler負責運行協程。 ide

相關文章
相關標籤/搜索