Linux之线程(二)

线程所独有的

虽然线程共享进程绝大部分数据,但为了实现独立调度执行,每条线程都有独属于自己的私有资源:

  1. 线程唯一标识 ID 内核层面的 LWP、用户态 pthread_t 线程 ID,用来区分同进程下不同执行流;
  2. 寄存器上下文 程序运行时的通用寄存器、程序计数器等,线程切换时会保存 / 恢复这组寄存器数据,保证执行不会错乱;
  3. 独立栈空间 函数调用、局部变量、函数返回地址全部存放在线程私有栈,多个线程函数调用互不干扰;
  4. errno 全局错误标记 每个线程有独立的 errno 副本,一个线程函数报错修改 errno,不会影响其他线程的错误判断;
  5. 私有信号屏蔽字 每条线程可以单独设置要屏蔽的信号,线程间信号屏蔽规则互不干涉;
  6. 独立调度优先级 内核调度器会依据每条线程自身的优先级分配 CPU 时间片,同一进程内不同线程可设置不同优先级。

创建一个线程的代价远小于创建一个新进程,删除也是一致的

代码

线程创建

pthread_create

参数说明

  1. pthread_t *thread:输出参数,创建成功后存入新线程 ID(你截图里打印的 tid)
  2. const pthread_attr_t *attr:线程属性,传nullptr使用默认属性
  3. void *(*start_routine)(void *):线程入口函数,返回void*、参数void*
  4. void *arg:传给线程函数的参数,任意类型指针

返回值

  • 0:创建成功
  • 非 0:错误码(如内存不足、权限错误)

不是lwp

十六进制打印

其实这个id是一个地址,具体是什么等一下来解释


pthread_self

作用

返回调用该函数的当前线程自身 ID,无参数、无失败返回值,永远有效


新线程的tid


新线程和主线程都有tid,并且是不一样的


线程资源共享

丰富一下


多个执行流进入函数----->重入

我们将print操作封装,发现线程都可以使用------代码是共享的


定义全局变量

让新线程对其进行++

我们观察到val的值是在变化的

以上证明多线程资源共享

代码异常

异常问题:任意线程异常奔溃,会导致整个进程挂掉

让线程一下子全部都创建出来

让线程只打印一次,让内容更加清晰

但是我们确发现打印出来并不是有序的,

循环里 char threadname[64] 是栈局部数组,每次循环覆盖内容; 创建子线程时直接传数组地址,子线程读取时数组内容早已被下一轮循环修改,线程 name 偶尔错乱。

这样会出现数据不一致的问题

除了上面这个可能,也会有下面这种情况

printf 是行缓冲,但多线程并发调用时,一行打印会被其他线程打断穿插。 多个线程同时执行 printf,操作系统线程调度会随时切换线程,导致文字错位、顺序杂乱。

相关推荐
进击的荆棘30 分钟前
Linux系统——库的原理与制作之ELF文件的形成与加载的过程(下)
linux·动静态库
CrazyMo_39 分钟前
鸿蒙高级——内存专用之linux-reserve-memory 方案简介
linux·运维·服务器
Sammyyyyy1 小时前
jev-ultrafast 实战:浏览器操作代理加本地 AI 网关,把云控制台配置做成自动化流水线
运维·人工智能·自动化·ai编程·servbay
灯澜忆梦1 小时前
【Linux】#5 | 文件与目录基础操作命令
java·linux·运维
逐梦之程1 小时前
EXCEL与DBC格式互转软件
运维·服务器·网络
yychen_java1 小时前
第十二篇:完整项目实战——构建可验证的能源智能运维 Agent 中枢
运维·人工智能·能源
9624561 小时前
餐饮 SaaS 优惠券系统架构演进(七)营销定价引擎设计:活动、会员价、优惠券、买赠如何在同一 PriceQuote 中可解释地组合
java·运维·算法
重生之高冷汉堡包1 小时前
什么是数据中心代理?原理拆解、类型区别、应用场景与选型指南
服务器·网络·数据库·安全·ip
Frank_refuel1 小时前
分布式IoT数据采集与存储系统(项目复盘)
运维·服务器
wuminyu1 小时前
stackChunkOop内部结构与GC屏障的配合工作原理剖析
java·linux·c语言·jvm·c++