Reference:https://time.geekbang.org/column/article/104521
協程的實現原理
協程不只在Go語言中實現了,其實目前大部分語言都實現了自己的一套協程,包括C#、erlang、python、lua、javascript、ruby等。
相對於協程,你可能對進程和線程更為熟悉。
進程一般代表一個應用服務,在一個應用服務中可以創建多個線程,
而協程與進程、線程的概念不一樣,可以將協程看作是一個類函數或者一塊函數中的代碼,可以在一個主線程里面輕松創建多個協程。
程序調用協程與調用函數不一樣的是,協程可以通過暫停或者阻塞的方式將協程的執行掛起,而其它協程可以繼續執行。這里的掛起只是在程序中(用戶態)的掛起,同時將代碼執行權轉讓給其它協程使用,待獲取執行權的協程執行完成之后,將從掛起點喚醒掛起的協程。 協程的掛起和喚醒是通過一個調度器來完成的。
相比線程,協程少了由於同步資源競爭帶來的CPU上下文切換,I/O密集型的應用比較適合使用,特別是在網絡請求中,有較多的時間在等待后端響應,協程可以保證線程不會阻塞在等待網絡響應中,充分利用了多核多線程的能力。而對於CPU密集型的應用,由於在多數情況下CPU都比較繁忙,協程的優勢就不是特別明顯了。
總結
協程和線程密切相關,協程可以認為是運行在線程上的代碼塊,協程提供的掛起操作會使協程暫停執行,而不會導致線程阻塞。
協程又是一種輕量級資源,即使創建了上千個協程,對於系統來說也不是很大的負擔,但如果在程序中創建上千個線程,那系統可真就壓力山大了。可以說,協程的設計方式極大地提高了線程的使用率。