自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 面試官:什么是協(xié)程,協(xié)程和線程的區(qū)別和聯(lián)系?

開發(fā) 后端
最近金三銀四,是面試的季節(jié)。在我的 Go 讀者交流群里出現(xiàn)了許多小伙伴在討論自己面試過(guò)程中所遇到的一些 Go 面試題。今天的男主角,是工程師的必修技能,那就是 “什么是協(xié)程,協(xié)程和線程的區(qū)別和聯(lián)系?”

[[395523]]

大家好,我是煎魚。

最近金三銀四,是面試的季節(jié)。在我的 Go 讀者交流群里出現(xiàn)了許多小伙伴在討論自己面試過(guò)程中所遇到的一些 Go 面試題。

今天的男主角,是工程師的必修技能,那就是 “什么是協(xié)程,協(xié)程和線程的區(qū)別和聯(lián)系?”

既要理解線程,還要講解協(xié)程,并且詮釋兩者間的區(qū)別,但是由于提到線程,就必然涉及進(jìn)程,因此本文將會(huì)同時(shí)梳理介紹 “進(jìn)程、協(xié)程、協(xié)程” 三者的隨筆知識(shí),希望能引發(fā)大家的一些思考。

吸魚之路開始。

進(jìn)程

進(jìn)程是什么

進(jìn)程是操作系統(tǒng)對(duì)一個(gè)正在運(yùn)行的程序的一種抽象,進(jìn)程是資源分配的最小單位。

進(jìn)程在操作系統(tǒng)中的抽象表現(xiàn)

為什么有進(jìn)程

為什么會(huì)有 ”進(jìn)程“ 呢?說(shuō)白了還是為了合理壓榨 CPU 的性能和分配運(yùn)行的時(shí)間片,不能 “閑著“。

在計(jì)算機(jī)中,其計(jì)算核心是 CPU,負(fù)責(zé)所有計(jì)算相關(guān)的工作和資源。單個(gè) CPU 一次只能運(yùn)行一個(gè)任務(wù)。如果一個(gè)進(jìn)程跑著,就把唯一一個(gè) CPU 給完全占住,那是非常不合理的。

那為什么要壓榨 CPU 的性能?因?yàn)?CPU 實(shí)在是太快,太快,太快了,寄存器僅僅能夠追的上他的腳步,RAM 和別的掛在各總線上的設(shè)備則更是望塵莫及。

多進(jìn)程的緣由

如果總是在運(yùn)行一個(gè)進(jìn)程上的任務(wù),就會(huì)出現(xiàn)一個(gè)現(xiàn)象。就是任務(wù)不一定總是在執(zhí)行 ”計(jì)算型“ 的任務(wù),會(huì)有很大可能是在執(zhí)行網(wǎng)絡(luò)調(diào)用,阻塞了,CPU 豈不就浪費(fèi)了?

進(jìn)程的上下文切換

這又出現(xiàn)了多進(jìn)程,多個(gè) CPU,多個(gè)進(jìn)程。多進(jìn)程就是指計(jì)算機(jī)系統(tǒng)可以同時(shí)執(zhí)行多個(gè)進(jìn)程,從一個(gè)進(jìn)程到另外一個(gè)進(jìn)程的轉(zhuǎn)換是由操作系統(tǒng)內(nèi)核管理的,一般是同時(shí)運(yùn)行多個(gè)軟件。

線程

有了多進(jìn)程,想必在操作系統(tǒng)上可以同時(shí)運(yùn)行多個(gè)進(jìn)程。那么為什么有了進(jìn)程,還要線程呢?

原因如下:

進(jìn)程間的信息難以共享數(shù)據(jù),父子進(jìn)程并未共享內(nèi)存,需要通過(guò)進(jìn)程間通信(IPC),在進(jìn)程間進(jìn)行信息交換,性能開銷較大。

創(chuàng)建進(jìn)程(一般是調(diào)用 fork 方法)的性能開銷較大。

大家又把目光轉(zhuǎn)向了進(jìn)程內(nèi),能不能在進(jìn)程里做點(diǎn)什么呢?

進(jìn)程由多個(gè)線程組成

一個(gè)進(jìn)程可以由多個(gè)稱為線程的執(zhí)行單元組成。每個(gè)線程都運(yùn)行在進(jìn)程的上下文中,共享著同樣的代碼和全局?jǐn)?shù)據(jù)。

多個(gè)進(jìn)程,就可以有更多的線程。多線程比多進(jìn)程之間更容易共享數(shù)據(jù),在上下文切換中線程一般比進(jìn)程更高效。

原因如下:

  • 線程之間能夠非常方便、快速地共享數(shù)據(jù)。
    • 只需將數(shù)據(jù)復(fù)制到進(jìn)程中的共享區(qū)域就可以了,但需要注意避免多個(gè)線程修改同一份內(nèi)存。
  • 創(chuàng)建線程比創(chuàng)建進(jìn)程要快 10 倍甚至更多。
    • 線程都是同一個(gè)進(jìn)程下自家的孩子,像是內(nèi)存頁(yè)、頁(yè)表等就不需要了。

協(xié)程是怎么回事

協(xié)程是什么

協(xié)程(Coroutine)是用戶態(tài)的線程。通常創(chuàng)建協(xié)程時(shí),會(huì)從進(jìn)程的堆中分配一段內(nèi)存作為協(xié)程的棧。

線程的棧有 8 MB,而協(xié)程棧的大小通常只有 KB,而 Go 語(yǔ)言的協(xié)程更夸張,只有 2-4KB,非常的輕巧。

協(xié)程的誕生

根據(jù)維基百科的說(shuō)法,馬爾文·康威于 1958 年發(fā)明了術(shù)語(yǔ) “coroutine” 并用于構(gòu)建匯編程序,關(guān)于協(xié)程最初的出版解說(shuō)在 1963 年發(fā)表。

也就是歷史上是先有的 “協(xié)程”,再有的 “線程”,線程是在在協(xié)程的基礎(chǔ)上添加了棧等功能后擴(kuò)展出來(lái)的。

但為什么一開始協(xié)程沒有火起來(lái)呢?這個(gè)比較難考證,大概率還是與 60 年前的計(jì)算機(jī)時(shí)代背景有關(guān)。

而如今人們把協(xié)程調(diào)度的邏輯更進(jìn)一步抽象為 “等 IO,讓出,IO 完畢”,在此基礎(chǔ)上人們發(fā)現(xiàn)協(xié)程的方式能解決多線程環(huán)境下很多代碼邏輯 “混亂”。

協(xié)程的優(yōu)勢(shì)

既然線程似乎已經(jīng)很好地填補(bǔ)了進(jìn)程的遺憾,那怎么又出來(lái)了一個(gè) “協(xié)程”,難道是重復(fù)造輪子嗎?

協(xié)程的優(yōu)勢(shì)(via InfoQ @八兩)如下:

  • 節(jié)省 CPU:避免系統(tǒng)內(nèi)核級(jí)的線程頻繁切換,造成的 CPU 資源浪費(fèi)。好鋼用在刀刃上。而協(xié)程是用戶態(tài)的線程,用戶可以自行控制協(xié)程的創(chuàng)建于銷毀,極大程度避免了系統(tǒng)級(jí)線程上下文切換造成的資源浪費(fèi)。
  • 節(jié)約內(nèi)存:在 64 位的Linux中,一個(gè)線程需要分配 8MB 棧內(nèi)存和 64MB 堆內(nèi)存,系統(tǒng)內(nèi)存的制約導(dǎo)致我們無(wú)法開啟更多線程實(shí)現(xiàn)高并發(fā)。而在協(xié)程編程模式下,可以輕松有十幾萬(wàn)協(xié)程,這是線程無(wú)法比擬的。
  • 穩(wěn)定性:前面提到線程之間通過(guò)內(nèi)存來(lái)共享數(shù)據(jù),這也導(dǎo)致了一個(gè)問題,任何一個(gè)線程出錯(cuò)時(shí),進(jìn)程中的所有線程都會(huì)跟著一起崩潰。
  • 開發(fā)效率:使用協(xié)程在開發(fā)程序之中,可以很方便的將一些耗時(shí)的IO操作異步化,例如寫文件、耗時(shí) IO 請(qǐng)求等。

協(xié)程本質(zhì)上就是用戶態(tài)下的線程,所以也有人說(shuō)協(xié)程是 “輕線程”,但我們一定要區(qū)分用戶態(tài)和內(nèi)核態(tài)的區(qū)別,很關(guān)鍵。

總結(jié)

歸歸根到底,在日?;蛎嬖囍杏龅?“什么是協(xié)程,協(xié)程和線程的區(qū)別和聯(lián)系?” 這類問題時(shí),面試者常規(guī)會(huì)把進(jìn)程、線程、協(xié)程都介紹一遍。

為了方便記憶和詮釋,推薦大家結(jié)合故事來(lái)講會(huì)比較好,這一塊可以參考阮一峰大神翻譯的《進(jìn)程與線程的一個(gè)簡(jiǎn)單解釋》,會(huì)帶來(lái)不少好感。

而最關(guān)鍵的部分,在于協(xié)程和線程的區(qū)別和聯(lián)系是什么?

我們可以通過(guò)文章中的介紹,從協(xié)程 -> 線程的歷史進(jìn)程來(lái)說(shuō)明。接著進(jìn)一步對(duì)比協(xié)程和線程兩者的優(yōu)勢(shì)和缺點(diǎn),就能比較好的詮釋區(qū)別和聯(lián)系了。

更優(yōu)秀的部分,可以詮釋完基本概念和區(qū)別后,進(jìn)一步延伸都你所面試的崗位,例如是 Go 語(yǔ)言,就可以介紹 Go 語(yǔ)言的協(xié)程的具體應(yīng)用和實(shí)現(xiàn)。

畢竟,Go 語(yǔ)言可以輕輕松松開數(shù)十萬(wàn)個(gè)協(xié)程,毫無(wú)波瀾。這樣能夠更好的體現(xiàn)你對(duì)協(xié)程、線程的知識(shí)深度和廣度應(yīng)用,而不是單純的背概念。

參考

線程和進(jìn)程的區(qū)別是什么?

有了多線程,為什么還要有協(xié)程?

進(jìn)程與線程的一個(gè)簡(jiǎn)單解釋

 

責(zé)任編輯:武曉燕 來(lái)源: 腦子進(jìn)煎魚了
相關(guān)推薦

2023-11-17 11:36:59

協(xié)程纖程操作系統(tǒng)

2021-09-10 17:02:43

Python協(xié)程goroutine

2021-09-16 09:59:13

PythonJavaScript代碼

2023-08-08 07:18:17

協(xié)程管道函數(shù)

2016-10-28 17:39:47

phpgolangcoroutine

2023-07-30 23:44:49

Go協(xié)程進(jìn)程

2024-12-03 15:15:22

2022-10-28 10:45:22

Go協(xié)程GoFrame

2020-11-29 17:03:08

進(jìn)程線程協(xié)程

2024-06-27 07:56:49

2025-02-28 09:04:08

2018-12-04 14:00:41

協(xié)程編程模式PHP

2023-12-05 13:46:09

解密協(xié)程線程隊(duì)列

2021-08-04 16:19:55

AndroidKotin協(xié)程Coroutines

2023-10-12 09:46:00

并發(fā)模型線程

2021-06-03 14:08:03

開發(fā)技能代碼

2021-06-04 14:28:07

協(xié)程線程Android開發(fā)

2023-07-27 13:46:10

go開源項(xiàng)目

2025-02-08 09:13:40

2023-10-24 19:37:34

協(xié)程Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)