国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

協程、線程和執行上下文

2019-11-10 22:22:19
字體:
來源:轉載
供稿:網友

摘要: 本文介紹協程、線程及它們執行的上下文等概念,同時給出注意事項。協程是用戶級的任務調度,線程是內核級的任務調度,而任務調度過程都涉及到上下文切換(保存與恢復),本文將從較為深刻的角度來闡述這些概念,及其相互關系。

協程和線程

線程在現代的系統里扮演的角色很重要,幾乎一個現代一點的,稍微復雜大型一點的程序,往往都會引入線程,實現某種意義的并行。線程存在廣泛的支持,從操作系統,到編譯器,再到語言的定義與實現者,他們都在努力讓線程更好用,也有更少的限制。相反協程的現實要慘淡很多,在操作系統那里很少有協程的影子;只有Windows里,存在一個協程的實現——fiber(在那里它被稱為纖程)。

從概念上來說,線程和協程最大的區別就是調度方式不同——線程是被動調度的,協程是主動調度的。也就是說,線程什么時候執行,什么時候不執行,完全是OS決定,線程是OS的菜,程序員最多只能主動讓線程停下來,卻很難讓線程主動運行起來。相反協程的執行與停止完全由程序員決定,何時執行、何時停止簡單地調用一個協助方法就可以完成。因為線程是被動調度的,所以線程需要大量同步方法;而協程是主動調度的,所以協程之間的同步可以很自然完成——該停該跑——就這簡單直接。

協程的概念很完美,使用可能也很方便。但是因為一些我還不了解的原因,在C/C++里并沒有廣泛使用協程庫可用,這是因為現在的OS和編譯器無法很好地支持協程的實現;這也許是歷史原因,線程在概念上與線程不相矛盾,但它的許多實現方式限制了實現通用安全的協程。在C語言和UNIX草莽朝代,實現一個協程要比實現一個函數(協程的一種特例)更困難,而對于當時來說,函數已經完全夠用了,如此協程被冷淡了。

在用戶層協程被死死地限制了,可是在linux內核里,它卻一個基本的構件——內核線程,在更多的時候,更一個協程。當然這句話是我自己說,在我很有限的Linux內核經驗上說的,極有可能是錯誤的。

執行上下文

線程是操作系統實現的,也是操作系統的調度單位。我們知道,所謂調度就是操作系統根據一些規則決定在何時中止一個線程操作,并在一個恰當的時候再喚醒這個線程。這里有個自然的問題,就是操作系統怎么實現中止與喚醒操作的?其時停止與喚醒操作都離不開CPU的支持,CPU在硬件上實現了中斷機制,OS使用中斷機制實現了線程調度。OS可以告訴CPU,每過100ms(毫秒)或10ms你就調用一下一段代碼——這就是所謂的時鐘中斷例程,OS在這一小段代碼里實現了線程的中止與喚醒。在這段代碼里,OS通常會做這些事:

保存一下當前的狀態,當前是哪個線程在執行,當前這個線程執行到哪里了,等等——這些狀態實際上就是當前CPU或CPU-Core里的數個特殊寄存器的數值。我們稱這些狀態可能放在一個結構體里,這個結構體又被稱為上下文(執行上下文)。干一些其它的事,如更新系統時間,看看有沒有什么其它OS需要定時去做的事,等等。根據一些規則(也就是調度策略),在所有已經中止的線程挑選一個,把之前保存起來的狀態恢復——實際上就是把之前保存在結構體的寄存器的值,再加載到相應寄存器里。最后,OS執行一個跳轉指令,把CPU的執行權限傳遞給剛才挑選的線程,如此這個線程就從之前停下來的地方接著跑起來了。也就是說,它被喚醒了。

在上面的說明,我們看到一次保存狀態和一次恢復狀態,所謂狀態就是上下文(狀態),而這個一次保存和一次恢復的過程稱為一次上下文切換——大概意思就是說,剛才CPU在干這塊的活,現在它又切換到另一塊地方干活了。

現在我們知道上下文切換,以及OS是如何實現上下文切換的了,那么有一個問題,就是程序員能不能在自己的程序里使用與OS相同功能的代碼,在自己的程序進行上下文切換?答案是: 完全可以。事實上,這就是實現協程的基本方法。程序在執行的時候是沒有函數這些概念的,諸如函數這些概念都上層語言及編譯器實現的抽象概念,CPU不認識。CPU只認識指令及指令操作的地址。

了解 C++ Boost 庫的人一定知道它最近新加了兩個庫: context 和 coroutine —— 看這個名字就知道,前者是實現了上下文切換的,后者是利用前者實現了用戶態協程的。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宜兰县| 咸宁市| 丹阳市| 上高县| 海阳市| 宁夏| 韶关市| 南投市| 盐城市| 嵊州市| 巴东县| 叙永县| 龙陵县| 车险| 吉木乃县| 安西县| 洛南县| 东莞市| 诸城市| 绥芬河市| 榆树市| 清新县| 南部县| 海门市| 雷波县| 津南区| 依兰县| 洛宁县| 济源市| 东方市| 渝中区| 镇安县| 孟津县| 京山县| 吴江市| 资阳市| 和静县| 屯留县| 镇赉县| 阿拉善左旗| 武功县|