【Linux】线程

线程的概念

线程是进程的一个执行流

线程的作用是执行进程中的一部分代码。

线程和进程不同的是,如果是父子进程,使用的是两个独立的虚拟地址空间;线程和父进程(主线程)之间使用的是同一份虚拟地址空间

线程是轻量级进程

每个线程都有自己的task_struct结构体对象,用来描述线程的属性,包括:

id、状态、优先级、上下文、栈等等。

要将线程管理起来,所以描述线程task_struct结构体的叫做TCB -- 线程控制块(Thread contral Block)

描述线程之后,就可以对线程进行管理。

但是,线程中的内容和进程的很像,Linux认为,没有必要再为线程创建一套管理的方式,直接复用就可以了。

因此,在Linux中,没有线程的概念,线程叫做 -- 轻量级进程

CPU眼里的线程

CPU是一个硬件,很被动。给它什么就执行什么,它不会区分是进程还是线程,只关task_struct。

在CPU看来,都是进程

一个进程可以创建很多线程,线程是进程的一个执行流。

所以CPU执行的task_struct,如果是1个,就是线程;如果>1个就是进程(多个线程)。

和之前的内容自洽

之前所讲的进程,就是单执行流的情况,一个进程内部只有一个task_struct。

进程的重新定义:进程是承担分配系统资源的基本实体。

线程引入Linux

前面提到,Linux中没有专门管理线程的算法,在Linux中是不存在线程这个概念的。

所以,Linux中是不可能有关于线程的系统调用的

在Linux中使用线程的接口,就必须使用原生线程库

程序员通过原生线程库创建线程,Linux就创建轻量级进程。

既满足了程序员创建线程的需求,又满足了Linux中没有线程的情况,双赢。

线程接口、实现

  • pthread_t* thread:线程标识符tid,是一个输出型参数。
  • const pthread_attr_t* attr:线程属性,当前阶段一律设成nullptr。
  • void* (*start_routine)(void *):是一个函数指针,线程执行的就是该函数中的代码。
  • void* arg:是上面函数指针指向函数的形参。
  • 返回值:线程创建成功返回0。

执行结果:

可以看到,定义的全局变量count同时被两个线程操作,地址都是0x601194。说明两个线程能共享这个全局变量

并且,在代码中,使用的是死循环,如果是单线程的程序,应该只会执行主线程或者只会执行新线程,现在两个都执行了,说明是并发的,能同时执行的。

因为Linux中没有线程的调用接口,需要使用原生线程库,所以在Makefile中需要连接原生线程库

线程的共有资源和私有资源

线程和进程的对比 - 优缺点

优点

  • 与进程切换相比,线程切换需要操作系统做的工作要少很多

        进程切换:PCB切换 + 上下文切换 + 虚拟地址空间切换 + 页表切换 

        线程切换:PCB切换 + 上下文切换

  • 创建一个新线程的代价要比创建一个新进程小得多,因为线程不会创建新的虚拟地址空间和页表。
  • 线程占用的资源要比进程少很多。
  • 能充分利用多处理器的可并行数量。
  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务。
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现。
  • I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

缺点

  • 性能损失

一个很少被外部事件阻塞的计算密集型线程往往无法与其它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销(线程切换),而可用的资源不变。

  • 缺乏访问权限

进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。

  • 编程难度提高

总结

线程是轻量级进程

进程是承担分配系统资源的基本实体

如果一个进程只有一个执行流,叫单执行流,也就是线程了。线程是进程的一个执行流。

因为线程的PCB和进程的PCB基本相同,为了避免代码冗余,Linux中没有创建新的线程管理方式,所以在Linux中没有线程的概念(因此线程是轻量级进程)。

正是因为Linux中没有线程的管理方式,所以也不可能提供线程的接口,所以必须使用原生线程库,所以在编译的时候,必须带上-l pthread,链接原生线程库。

线程是存在于一个进程中的,所以线程的大部分资源都是共享的,因此,线程间相互通信非常简单,不需要进程间通信使用(消息队列,信号量、管道等方式),但是,为了不造成紊乱,线程间也必须有自己独立的空间。也就是:

1、PCB独立

2、栈结构私有

3、上下文数据私有

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux线程通信是指在Linux操作系统中,不同线程之间进行信息交流和数据共享的机制。线程通信是多线程编程中非常重要的一部分,它可以实现线程之间的协作和同步。 在Linux中,线程通信可以通过以下几种方式实现: 1. 共享内存:多个线程可以通过共享内存区域来进行数据的读写。线程可以访问同一块内存区域,从而实现数据的共享。需要注意的是,由于多个线程同时访问共享内存可能会导致数据竞争和不一致性问题,因此需要使用互斥锁或其他同步机制来保证数据的一致性。 2. 信号量:信号量是一种用于线程同步的机制,它可以用来控制对共享资源的访问。通过使用信号量,线程可以等待某个条件满足后再继续执行,或者通知其他线程某个条件已经满足。 3. 互斥锁:互斥锁是一种用于保护共享资源的机制,它可以确保在同一时间只有一个线程可以访问共享资源。当一个线程获得了互斥锁后,其他线程需要等待该线程释放锁才能继续执行。 4. 条件变量:条件变量是一种用于线程同步的机制,它可以让线程等待某个条件满足后再继续执行。条件变量通常与互斥锁一起使用,以确保在等待条件时不会发生竞争条件。 5. 管道:管道是一种用于进程间通信的机制,但在Linux中也可以用于线程间通信。通过管道,一个线程可以将数据写入管道,另一个线程可以从管道中读取数据。 6. 消息队列:消息队列是一种用于进程间通信的机制,但在Linux中也可以用于线程间通信。通过消息队列,一个线程可以将消息发送到队列中,另一个线程可以从队列中接收消息。 7. 套接字:套接字是一种用于网络通信的机制,但在Linux中也可以用于线程间通信。通过套接字,不同线程可以通过网络协议进行通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值