Linux线程(1)——什么是线程?

        线程是参与系统调度的最小单位。它被包含在进程之中,是进程中的实际运行单位。一个线程指的是进程中一个单一顺序的控制流(或者说是执行路线、执行流),一个进程中可以创建多个线程,多个线程实现并发运行,每个线程执行不同的任务。譬如某应用程序设计了两个需要并发运行的任务 task1 和 task2,可将两个不同的任务分别放置在两个线程中。

线程是如何创建起来的?

        当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread),因为它是程序一开始时就运行的线程。应用程序都是以main()作为入口开始运行的,所以 main()函数就是主线程的入口函数,main()函数所执行的任务就是主线程需要执行的任务。

        所以由此可知,任何一个进程都包含一个主线程,只有主线程的进程称为单线程进程;既然有单线程进程,那自然就存在多线程进程,所谓多线程指的是除了主线程以外,还包含其它的线程,其它线程通常由主线程来创建(调用 pthread_create 创建一个新的线程),那么创建的新线程就是主线程的子线程。

        主线程的重要性体现在两方面:

  1. 其它新的线程(也就是子线程)是由主线程创建的;
  2. 主线程通常会在最后结束运行,执行各种清理工作,譬如回收各个子线程。

线程的特点?

        线程是程序最基本的运行单位,而进程不能运行,真正运行的是进程中的线程。当启动应用程序后,系统就创建了一个进程,可以认为进程仅仅是一个容器,它包含了线程运行所需的数据结构、环境变量等信息。

        同一进程中的多个线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack,我们称为线程栈),自己的寄存器环境(register context)、自己的线程本地存储(thread-local storage)。

        在多线程应用程序中,通常一个进程中包括了多个线程,每个线程都可以参与系统调度、被 CPU 执行, 线程具有以下一些特点:

  1. 线程不单独存在、而是包含在进程中;
  2. 线程是参与系统调度的基本单位;
  3. 可并发执行。同一进程的多个线程之间可并发执行,在宏观上实现同时运行的效果;
  4. 共享进程资源。同一进程中的各个线程,可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址; 此外,还可以访问进程所拥有的已打开文件、定时器、信号量等等。

线程与进程?

        进程创建多个子进程可以实现并发处理多任务(本质上便是多个单线程进程),多线程同样也可以实现 (一个多线程进程)并发处理多任务的需求,那我们究竟选择哪种处理方式呢?首先我们就需要来分析下多进程和多线程两种编程模型的优势和劣势。

        多进程编程的劣势:

  1. 进程间切换开销大。多个进程同时运行(指宏观上同时运行,无特别说明,均指宏观上),微观上依然是轮流切换运行,进程间切换开销远大于同一进程的多个线程间切换的开销,通常对于一些中小型应用程序来说不划算。
  2. 进程间通信较为麻烦。每个进程都在各自的地址空间中、相互独立、隔离,处在于不同的地址空间中,因此相互通信较为麻烦。
  3. 同一进程的多个线程间切换开销比较小。
  4. 同一进程的多个线程间通信容易。它们共享了进程的地址空间,所以它们都是在同一个地址空间中,通信容易。
  5. 线程创建的速度远大于进程创建的速度。
  6. 多线程在多核处理器上更有优势!

        综上所述,多线程编程相比于多进程编程的优势是比较明显的,在实际的应用当中多线程远比多进程应用更为广泛。那既然如此,为何还存在多进程编程模型呢?难道多线程编程就不存在缺点吗?当然不是,多线程也有它的缺点、劣势,譬如多线程编程难度高,对程序员的编程功底要求比较高,因为在多线程环境下需要考虑很多的问题,例如线程安全问题、信号处理的问题等,编写与调试一个多线程程序比单线程程序困难得多。

        当然除此之外,还有一些其它的缺点,这里就不再一一列举了。多进程编程通常会用在一些大型应用程序项目中,譬如网络服务器应用程序,在中小型应用程序中用的比较少。

并发和并行

        在前面的内容中,曾多次提到了并发这个概念,与此相类似的概念还有并行、串行,这里和大家聊一聊这些概念含义的区别。

        对于串行比较容易理解,它指的是一种顺序执行,譬如先完成 task1,接着做 task2、直到完成 task2,然后做 task3、直到完成 task3……依次按照顺序完成每一件事情,必须要完成上一件事才能去做下一件事,只有一个执行单元,这就是串行运行。

         并行与串行则截然不同,并行指的是可以并排/并列执行多个任务,这样的系统,它通常有多个执行单元,所以可以实现并行运行,譬如并行运行 task1、task2、task3。

         并行运行并不一定要同时开始运行、同时结束运行,只需满足在某一个时间段上存在多个任务被多个执行单元同时在运行着,譬如:

         相比于串行和并行,并发强调的是一种时分复用,与串行的区别在于,它不必等待上一个任务完成之后再做下一个任务,可以打断当前执行的任务切换执行下一个任何,这就是时分复用。在同一个执行单元上, 将时间分解成不同的片段(时间片),每个任务执行一段时间,时间一到则切换执行下一个任务,依次这样轮训(交叉/交替执行),这就是并发运行。如下图所示:

         需要注意,并行运行情况下的多个执行单元,每一个执行单元同样也可以以并发方式运行。

        从通用角度上介绍完这三个概念之后,类比到计算机系统中,我们需要知道两个前提条件:

  1. 多核处理器和单核处理器:对于单核处理器来说,只有一个执行单元,同时只能执行一条指令;而对于多核处理器来说,有多个执行单元,可以并行执行多条指令,譬如 8 核处理器,那么可以并行执行 8 条不同的指令。
  2. 计算机操作系统中,通常同时运行着几十上百个不同的线程,在单核或多核处理系统中都是如此!

        对于单核处理器系统来说,它只有一个执行单元,只能采用并发运行系统中的线程,而肯定不可能是串行,而事实上确实如此。内核实现了调度算法,用于控制系统中所有线程的调度,简单点来说,系统中所有参与调度的线程会加入到系统的调度队列中,它们由内核控制,每一个线程执行一段时间后,由系统调度切换执行调度队列中下一个线程,依次进行。

        对于多核处理器系统来说,它拥有多个执行单元,在操作系统中,多个执行单元以并行方式运行多个线程,同时每一个执行单元以并发方式运行系统中的多个线程。

        同时运行

        计算机处理器运行速度是非常快的,在单个处理核心虽然以并发方式运行着系统中的线程(微观上交替 /交叉方式运行不同的线程),但在宏观上所表现出来的效果是同时运行着系统中的所有线程,因为处理器的运算速度太快了,交替轮训一次所花费的时间在宏观上几乎是可以忽略不计的,所以表示出来的效果就是同时运行着所有线程。

        这就好比现实生活中所看到的一些事情,它所给带来的视角效果,譬如一辆车在高速上行驶,有时你会感觉到车的轮毂没有转动,一种视角暂留现象,因为车轮转动速度太快了,人眼是看不清的,会感觉车轮好像是静止的,事实上,车轮肯定是在转动着。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值