一、Linux下线程的基本概念

Ⅰ、Linux线程的基本概念

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。
线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。

Ⅱ、Linux线程的特点

进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

总的来说就是:进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。(下面的内容摘自Linux下的多线程编程)

使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。

使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。

除了以上所说的特点外,不和进程比较,多线程程序作为一种多任务、并发的工作方式,当然有以下的特点:

  • 线程是资源竞争的基本单位。
    操作系统有很多资源。进程与进程之间要竞争操作系统资源,当一个进程申请得到一大堆资源。而这些资源又会分配给线程。一个进程内部有多个线程,去竞争进程所获得的资源。所以说线程是资源竞争的基本单位。
  • 线程是程序执行的最小单位
    当用户让进程去执行某个任务时,进程又会将任务细化。进程内部有很多线程,让这些线程去执行。
  • 线程共享进程数据,但也拥有自己独立的一部分数据: 线程ID ,一组寄存器,栈,errno值,信号。
    其中最重要的数据是栈和寄存器。私有栈是为了保存临时变量,便于函数调用等操作。私有寄存器是为了方便线程切换,保存上下文。

Ⅲ、Linux进程与线程的联系

在Linux下并没有专门为线程设计这么一个概念,也就是说没有真正意义上的线程,它在linux下是由进程模拟的,可以认为所有的PCB都可以称为轻量级进程(不一定是进程,也可能是线程)。进程是分配系统资源的一个实体,而线程是CPU调度的基本单位。

在单个程序中同时运行多个线程完成不同的工作,称为多线程。相对来说,多进程相对稳定,多线程相对不稳定。可以认为,进程是分配系统资源的一个实体,而线程是CPU调度的基本单位。

进程具有独立的地址空间,而线程并没有,同一进程内部的线程共享进程的地址空间。
由于Linx下没有真正的线程,Linux用进程来描述线程和组织线程。所以在Linux下只有轻量级的线程,操作系统是看不到线程的TCB的。

Ⅳ、线程的优点

  • 创建一个新线程的代价要比创建一个新进程小得多,释放成本也更低。因为创建一个进程就意味着要创建PCB,分配虚拟地址空间,页表,物理内存等系统资源,而创建一个线程只需要创建一个PCB(TCB)即可。
  • 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多。进程切换,需要切换对应的虚拟地址空间,更换页表等。过程繁琐。
  • 线程占用的资源要比进程少很多。
  • 能充分利用多处理器的可并行数量。
  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务。比如打开一个网易云音乐播放器,你可以一边下载,一边在线听歌。这就是两个线程在工作。
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现 I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。
  • 进程可以将线程串行执行变成并行执行。最后汇总,提高效率。但是尽量不要创建太多线程,线程切换也是需要成本的。
  • 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。
  • 使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
  • 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。

Ⅴ、线程的缺点

  • 性能损失
    一个很少被外部事件阻塞的计算密集型线程往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。
  • 健壮性降低
    编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。一个线程挂掉,因为线程共享一块资源。其他线程也会挂掉。进而导致进程退出,资源被回收。
  • 缺乏访问控制
    进程是访问控制的基本粒度,在一个线程中调⽤用某些OS函数会对整个进程造成影响。多线程访问临界资源,它的访问控制是由编程者决定。
  • 编程难度提高
    编写与调试一个多线程程序比单线程程序困难得多,基于同步互斥。你需要不断的加锁。

Ⅵ、线程的4种状态

状态含义
就绪(Ready)线程能够运行,但在等待可用的处理器。可能刚刚创建启动,或刚刚从阻塞中恢复,或者被其他线程抢占
运行(Running)线程正在运行。在多处理器系统中,可能有多个线程处于运行态
阻塞(Blocked)线程由于等待处理器外的其他条件无法运行,如条件变量的改变、加锁互斥量或I/O操作结束
终止(Terminated)线程从起始函数中返回,或者调用pthread_exit,或者被取消,终止自己并完成所有资源清理工作。不是被分离,也不是被连接

a.就绪:当线程刚被创建时就处于就绪状态,或者当线程被解除阻塞以后也会处于就绪状态。就绪的线程在等待一个可用的处理器,当一个运行的线程被抢占时,它立刻又回到就绪状态。
b.运行:当处理器选中一个就绪的线程执行时,它立刻变成运行状态。
c.线程阻塞的原因可能是:
1. 试图加锁一个已经被锁住的互斥量
2. 等待某个条件变量
3. 调用Singwait等待尚未发生的信号
4. 执行无法立即完成的I/O操作
5. 线程还会由于如内存页错误之类的系统操作而被阻塞

d.终止:线程通常启动函数中返回来终止自己,或者调用pthread_exit退出,或者取消线程。
在这里插入图片描述
-------------------------------------------------------------End------------------------------------------------------------------------
作者:踏着时光去旅行
时间:2019.04.16

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值