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