【node學習】協程

協程

要理解generator就必須知道一個概念,那就是協程javascript

1. 基本概念

協程,又成爲微線程(coroutine)。html

進程(process) vs 線程(thread)java

咱們都知道在操做系統級別上有兩個重要的概念(也是實體):進程(process)和線程(thread),這兩個東西是用於操做系統模擬並行的,在單個CPU上,os經過調度算法,讓CPU輪流執行線程或者進程,來達到程序的併發執行。node

那麼協程又是什麼?首先要明確的是,協程是編譯器級別的,而並不是線程和進程同樣是操做系統級別的。協程的實現,經過是對某個語言作相應的提議,而後經過後成編譯器標準,而後編譯廠商來實現該機制。git

2. 做用

協程的做用是什麼?github

簡單來講,就是實現函數的分段式執行。就是一個函數的執行能夠主動放棄CPU的控制權,先掛起,讓其餘的函數先執行,而後在返回,從上次執行結束的地方繼續執行。算法

這樣看起來很像是多線程輪流執行。可是卻有着很大的區別:協程是一個線程執行編程

  • 由於是一個線程執行,因此不存在線程的切換,而是由程序自身控制,也就不存在所謂的線程切換的開銷。安全

  • 不須要多線程的鎖機制。由於只有一個線程,也就不存在同時寫變量的衝突。在協程中控制共享資源不加鎖,只須要判斷狀態就行了。這也說明協程的執行效率很高一些。網絡

舉個生產者消費者模型基於搶佔式多線程編程的實現(僞代碼)

// 資源,隊列容器
var q = [];

// 消費者進程
loop(); // 循環等待
lock(q); // 加鎖
var item = getResourceFrom(q); // 獲取資源
unlock(q); // 操做結束,資源解鎖
operatingResource(item);
sleep;

// 生成者線程
loop(); // 循環等待
var item = createResource(p); // 生產資源
lock(q); // 加鎖
q.push(item); // 寫入資源
unlock(q); // 解鎖

能夠看到,以上的代碼中有兩個特色

  1. 對資源操做須要進行加鎖和解鎖的操做。(保證線程安全)

  2. 消費者線程必須經過sleep,讓出CPU,用於執行生產者線程使用。

那麼若是是協程的編程模式,就簡單地多。

var q = [];
var count = 0;

// 消費者
function *consumer() {
    while (true){
       var item = yield producer();
       console.log(item); 
    }
}

// 生產者
function producer() {
    q.push(count++);
}

function main () {
    const consumerGen = consumer();
    // 咱們能夠經過代碼來控制其交替執行

    // 執行到獲取item以前,放棄執行權,先執行producer(),
    consumerGen.next();
    // 以後能夠獲取item,而後再放棄執行權,執行producer,一直循環
    consumerGen.next(q.shift()); // 0
    consumerGen.next(q.shift()); // 1
    consumerGen.next(q.shift()); // 2
    consumerGen.next(q.shift()); // 3
    consumerGen.next(q.shift()); // 4
    consumerGen.next(q.shift()); // 5
}

main();

最後說幾句

很久在這上面寫博客了,最近一直忙於畢業設計學習node

參考

  1. 協程-廖雪峯

  2. C++ 協程與網絡編程

  3. 談談協程和C語言的協程

  4. 協程(Coroutine)並非真正的多線程

  5. 協程(一)原理

相關文章
相關標籤/搜索