一、MySQL使用多線程,而Oracle和PostgreSQL使用多進程的原因
傳統(tǒng)的unix系統(tǒng),早期沒有提供多線程,只有多進程。linux是最近的版本才加入多線程支持,以前一直都是多進程。windows很早就支持多線程,本地應(yīng)用大部分也是多線程。因此oracle在windows上一直都是多線程,在unix上才是多進程。多進程的好處是,一個進程崩潰不會影響其他進程,多線程的好處是不需要共享內(nèi)存這樣的手段來訪問數(shù)據(jù)庫緩沖區(qū)
諸如Oracle這種商業(yè)數(shù)據(jù)庫,基本都支持多種Process Models, Oracle默認是多進程。根據(jù)Understanding MySQL Internals所說, MySQL一開始是Solaris上的 :因此,在1996年5月,MySQL 1.0版本發(fā)布給一個有限的小組,隨后在1996年10月發(fā)布了3.11.1版本的公開版本。最初的公開發(fā)行版僅為Solaris提供了一個二進制發(fā)行版。一個月后,源代碼和Linux二進制文件發(fā)布了。
這本書也提及了,為什么MySQL用多線程:就像一個好的騎手與馬融為一體一樣,Monty(MySQL的作者)也與計算機融為一體。看到系統(tǒng)資源被浪費,他認為可以提升利用率。他有足夠的信心能夠編寫幾乎沒有錯誤的代碼,處理線程呈現(xiàn)的并發(fā)性問題,甚至可以使用一個小堆棧。
PostgreSQL的原因可以在The design of Postgres中找到:然而,這種方法需要構(gòu)建一個相當完整的專用操作系統(tǒng)。相比之下,每個用戶一個進程模型實現(xiàn)起來更簡單,但在大多數(shù)傳統(tǒng)操作系統(tǒng)上的性能不太好。由于我們有限的編程資源,我們在深思熟慮之后決定使用進程每用戶模型架構(gòu)來實現(xiàn)PostgreSQL。
總而言之,最根本的原因主要是當年操作系統(tǒng)對線程支持不給力,而MySQL是特例,因為開發(fā)者喜歡挑戰(zhàn)(不過事實上,那個時候的線程支持已經(jīng)基本完善了。MySQL后于Oracle和PostgreSQL)。
二、多線程與多進程
1、為什么要引入進程
多道程序設(shè)計的特點是多道,宏觀上并行,微觀上串行,而引入多道批處理系統(tǒng)就是為了提高系統(tǒng)資源的利用率,盡量使cpu處于繁忙狀態(tài),使各種資源能夠得到充分利用。在多道程序同時運行的環(huán)境下,允許多個程序并發(fā)執(zhí)行,此時他們將失去封閉性,并具有間斷性及不可再現(xiàn)性的特征,程序本身是一組執(zhí)行特定功能的指令的集合,是一個靜態(tài)的概念,無法描述程序在內(nèi)存中何時執(zhí)行,何時停頓,也無法看出它與其它執(zhí)行程序的關(guān)系,因此,程序這個靜態(tài)的概念已不能如實反映程序并發(fā)執(zhí)行過程的特征,為了能夠更好的描述和控制程序的并發(fā)執(zhí)行,實現(xiàn)操作系統(tǒng)的并發(fā)性和共享性,我們引入了進程這一概念。
為了更好的理解進程,需要明白并發(fā)和并行的區(qū)別。并發(fā)是指兩個或多個事件在同一時間間隔內(nèi)發(fā)生,比如早上8:00-9:00這一時間間隔內(nèi)你先洗漱然后再吃飯就是指的吃飯和洗漱這兩個事件并發(fā),但是為什么說多道程序設(shè)計下是微觀上并行呢,可以這么理解,操作系統(tǒng)把這一時間間隔看成了一個時刻,那么在這一時刻,操作系統(tǒng)只知道你干完了吃飯和洗漱這兩件事,并且操作系統(tǒng)是通過分時來實現(xiàn)并發(fā)的。并行是指在同一時刻完成兩種或者以上的工作,需要硬件的支持,通俗點理解就是并發(fā)是指兩個事件或多個事件有先后順序的執(zhí)行,而并行是指兩個事件或多個事件同時進行的。
2、什么是多進程
多進程就是指計算機同時執(zhí)行多個進程,一般是同時運行多個軟件。前面提到了引入進程就是為了能夠更好的描述程序的并發(fā)執(zhí)行,可想而知,進程是與資源有關(guān)的,所以進程就是進程實體的運行過程,是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位。進程實體是由程序段,相關(guān)數(shù)據(jù)段和PCB組成,而PCB是進程控制塊,是為了使參與并發(fā)執(zhí)行的程序能獨立運行而專門配置的一個數(shù)據(jù)結(jié)構(gòu),注意PCB是進程存在的少數(shù)標志。進程有用戶進程和系統(tǒng)進程之分,其中凡是用于完成操作系統(tǒng)的各種功能的進程就是系統(tǒng)進程,而所有由用戶啟動的進程都是用戶進程。
3、為什么要引入線程
前面提到過進程是與資源有關(guān)的,而進程又是動態(tài)的,因此進程進行切換時需要占用系統(tǒng)較多的開銷,影響了系統(tǒng)的并發(fā)性能,那么有沒有什么辦法可以盡量的降低系統(tǒng)開銷呢,于是引入了線程,盡量減小程序在并發(fā)執(zhí)行時所付出的時空開銷,提高操作系統(tǒng)的并發(fā)性能。
4、什么是多線程
多線程就是指一個進程中同時有多個線程正在執(zhí)行。線程是一個基本的cpu執(zhí)行單元,是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,可以與同屬于一個進程的其他線程共享進程所擁有的全部資源。引入線程之后,進程只作為除cpu以外系統(tǒng)資源的分配單元,線程則作為處理機的分配單元。
線程的實現(xiàn)可以分為用戶級線程和內(nèi)核級線程,在用戶級線程中,有關(guān)線程管理的所有工作都有應(yīng)用程序完成,內(nèi)核意識不到線程的存在。在內(nèi)核級線程中,線程管理的所有工作都是內(nèi)核完成,應(yīng)用程序無權(quán)管理線程。因此可以理解為多線程是一種執(zhí)行模型,包括多對一模型,一對一模型,多對多模型。
多對一模型:將多個用戶級線程映射到一個內(nèi)核級線程,線程管理在用戶空間完成。
優(yōu)點:線程管理是在用戶空間進行的,對于線程的管理不涉及內(nèi)核的服務(wù),因此效率比較高。缺點:由于用戶級線程對操作系統(tǒng)不可見,即多個用戶級線程實際上操作系統(tǒng)只會認為其只有一個用戶級線程,當一個用戶級線程在使用內(nèi)核服務(wù)時被阻塞,那么整個進程都會被阻塞,即其他的用戶級線程也不能運行了。另外,此模式下,多個線程不能并行地運行在多處理機上。一對一模型:將每個用戶級線程映射到一個內(nèi)核級線程。
優(yōu)點:當一個線程被阻塞時,允許另一個線程繼續(xù)執(zhí)行,所以并發(fā)性能較強。缺點:每創(chuàng)建一個用戶級線程都需要創(chuàng)建一個內(nèi)核級線程,這樣導(dǎo)致了創(chuàng)建線程的開銷較大,會影響程序的性能。多對多模型:將n個用戶級線程映射到m個內(nèi)核級線程,要求m<=n。
特點:是前兩種模型的折中,即克服了多對一模型的并發(fā)度不高的缺點,也克服了一對一模型的開銷太大的缺點。
5、進程和線程的比較
引入線程之后,線程是獨立調(diào)度的基本單位,進程是擁有資源的基本單位,不僅進程之間可以并發(fā)執(zhí)行,并且線程之間也可以并發(fā)執(zhí)行,使得操作系統(tǒng)具有更好的并發(fā)性,因為線程不擁有系統(tǒng)資源故使用線程調(diào)度時系統(tǒng)開銷小。
通俗的講,多線程的問題是多個人同時吃一道菜的時候容易發(fā)生爭搶,例如兩個人同時夾一個菜,一個人剛伸出筷子,結(jié)果伸到的時候已經(jīng)被夾走菜了,此時就必須等一個人夾一口之后,在還給另外一個人夾菜,也就是說資源共享就會發(fā)生沖突爭搶。對于 Windows 系統(tǒng)來說,【開桌子】的開銷很大,因此 Windows 鼓勵大家在一個桌子上吃菜。因此 Windows 多線程學(xué)習(xí)重點是要大量面對資源爭搶與同步方面的問題。對于 Linux 系統(tǒng)來說,【開桌子】的開銷很小,因此 Linux 鼓勵大家盡量每個人都開自己的桌子吃菜。這帶來新的問題是:坐在兩張不同的桌子上,說話不方便。因此,Linux 下的學(xué)習(xí)重點大家要學(xué)習(xí)進程間通訊的方法。
開桌子是指創(chuàng)建進程,開銷這里主要指的是時間開銷??梢宰鰝€實驗:創(chuàng)建一個進程,在進程中往內(nèi)存寫若干數(shù)據(jù),然后讀出該數(shù)據(jù),然后退出。此過程重復(fù) 1000 次,相當于創(chuàng)建/銷毀進程 1000 次。測試結(jié)果是:UbuntuLinux:耗時 0.8 秒;Windows7:耗時 79.8 秒。兩者開銷大約相差一百倍。
這意味著,在 Windows 中,進程創(chuàng)建的開銷不容忽視。換句話說就是,Windows 編程中不建議你創(chuàng)建進程,如果你的程序架構(gòu)需要大量創(chuàng)建進程,那么較好是切換到 Linux 系統(tǒng)。
大量創(chuàng)建進程的典型例子有兩個:
gnu autotools 工具鏈:用于編譯很多開源代碼的,他們在 Windows 下編譯速度會很慢,因此軟件開發(fā)人員較好是避免使用 Windows。服務(wù)器:某些服務(wù)器框架依靠大量創(chuàng)建進程來干活,甚至是對每個用戶請求就創(chuàng)建一個進程,這些服務(wù)器在 Windows 下運行的效率就會很差。這”可能”也是放眼全世界范圍,Linux 服務(wù)器遠遠多于 Windows 服務(wù)器的原因。延伸閱讀1:PostgreSQL簡介
PostgreSQL是一款高級的企業(yè)級開源關(guān)系數(shù)據(jù)庫,支持 SQL(關(guān)系型)和 JSON(非關(guān)系型)查詢。它是一個高度穩(wěn)定的數(shù)據(jù)庫管理系統(tǒng),依托 20 多年的社區(qū)發(fā)展,造就了其高水平的故障恢復(fù)能力、完整性和正確性。PostgreSQL 可用作很多 Web、移動、地理空間和分析應(yīng)用程序的主要數(shù)據(jù)存儲或數(shù)據(jù)倉庫。最新主要版本為 PostgreSQL 12。