目录

为什么MySQL使用多线程,而Oracle和PostgreSQL使用多进程

MySQL使用多线程,而Oracle和PostgreSQL使用多进程的原因:主要是当年操作系统对线程支持不给力,而MySQL是特例,因为开发者喜欢挑战,不过事实上,那个时候的线程支持已经基本完善了,MySQL后于Oracle和PostgreSQL。

一、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的作者)也与计算机融为一体。看到系统资源被浪费,他认为可以提升利用率。他有足够的信心能够编写几乎没有错误的代码,处理线程呈现的并发性问题,甚至可以使用一个小堆栈。

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。

一站式研发项目管理平台 PingCode

一站式研发项目管理平台 PingCode

支持敏捷\瀑布、知识库、迭代计划&跟踪、需求、缺陷、测试管理,同时满足非研发团队的流程规划、项目管理和在线办公需要。