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