【Linux】线程

本文介绍了Linux下的线程概念,指出Linux通过轻量级进程模拟线程。线程具有创建成本低、资源占用少等优点,但也存在共享资源带来的同步问题。文章详细讲解了pthread线程库的使用,包括线程创建、终止、等待、获取线程ID和线程分离等操作,并强调了pthread库在Linux中的重要性。
摘要由CSDN通过智能技术生成

前言

目录
1.Linux下的线程概念
2.Linux线程控制:pthread线程库
在单执行流的进程中,此执行流独占了进程的所有资源

在一个进程内部,有时不一定只有一个执行流,在多执行流下,多个执行流共享了进程的地址空间,我们把“一个程序内部的控制序列”叫做线程

线程本质是在进程的地址空间内运行
进程的切换涉及到页表映射的切换,而线程的切换只是切换了指令序列而在同一个地址空间中进行

那么我们给出下面两个重要概念

  • 进程是操作系统分配资源的基本实体
  • 线程是进程内部的一个执行流

举个栗子:在这里插入图片描述
在现实生活中,假如我们把社会资源的基本单位看作是家庭,比如我们经常以家庭年收入统计社会财富的分配状况,那么此时:

  • 操作系统—>社会
  • 进程—>家庭
  • 线程—>家庭成员

家庭成员共享了家庭的资源,家庭成员之间有共享的资源,也有私人的小秘密。

透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

线程可以被创建、等待、终止、控制
家庭有生老病死、家规等等…

1.Linux下的线程概念

在Linux下,其实没有真正意义上的线程概念,是用进程来模拟的

Linux的进程叫做轻量级进程

LWP是轻量级进程,在Linux下进程是资源分配的基本单位线程是cpu调度的基本单位,而线程使用进程pcb描述实现,操作系统在创建线程时给每个线程都创建一个pcb结构体,并且同一个进程中的所有pcb共用同一个虚拟地址空间,因此相较于传统进程更加的轻量化有了更多执行流之后。进程变成了分配资源的基本实体,进程一旦被创建好之后,里面可能有多个执行流

与进程相比,线程在CPU执行时可能更加轻量化:pcb上下文肯定要切换,但是线程的地址空间、页表不用换CPU调度时,看到的是LWP,也就是轻量级进程Light Weight Process

在这里插入图片描述

1.1 线程的优点

  • 创建一个新线程的代价要比创建一个新进程小得多
  • 与进程之间的切换相比,线程之间的切换需要OS的工作量更少
  • 线程占用的资源比进程少得多

1.2 线程能够看到进程的所有资源,因为所有PCB都共享地址空间

  • 好处:线程间通信成本低
  • 坏处:存在大量的临界资源,势必需要使用各种互斥和同步机制保证临界资源的安全

1.3 线程异常

线程是进程的一个执行分支,当发生野指针/除0等异常操作导致线程退出的同时,也意味着进程触发了该错误,操作系统会给进程发送信号,终止进程。这体现了多线程下鲁棒性降低了。

1.4 线程的共享与独享

线程共享

  • 文件描述符表
  • 每种信号的处理方式
  • 工作目录
  • 用户id组id

独有:

  • 上下文数据(寄存器):体现了多个线程是可以切换的
  • 独立的栈结构:体现了线程是独立运行的,各自的上下文数据不会互相影响

2.Linux线程控制:pthread线程库

首先要强调一点:pthread库并不是系统库,而是Linux下为了模拟线程而采用的第三方库。本质是封装了对于轻量级进程的某些操作。

链接这些线程函数库时要使用编译器命令的“-lpthread”选项
接口:
pthread_create()
pthread_join()
pthread_cancel()
pthread_exit()
pthread_self()

2.1线程的创建

功能: 创建一个新的线程
原型

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine)(void*), void *arg);

4个参数

  • thread:返回线程ID,这是进程地址空间的共享区的地址
  • attr:设置线程的属性,attr为NULL表示使用默认属性
  • start_routine:是个函数地址,线程启动后要执行的函数
  • arg:传给线程启动函数的参数,如果需要传入多个参数,可以用结构体封装

返回值: 成功返回0;失败返回错误码
在这里插入图片描述

让我们来玩一玩线程的创建,这边我们在main函数,也就是主线程创建了新线程,又在新线程中创建了另外5个更新的线程,使用ps -aL 命令查看轻量级进程

#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
void* routine(void* args) {
   
  while(true) {
   
    cout << "I am a thread" <<  endl;
    sleep(1);
  }
  return nullptr;
}
void* ThreadRoute(void* args) {
   
  pthread_t tids[5];
  for(int i = 0; i < 5; i++) {
   
    pthread_create(tids+i, nullptr, routine, nullptr);
  }
  for(int i = 0; i < 5; i++) {
   
    
  • 12
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DanteIoVeYou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值