线程所独有的
虽然线程共享进程绝大部分数据,但为了实现独立调度执行,每条线程都有独属于自己的私有资源:
- 线程唯一标识 ID 内核层面的 LWP、用户态 pthread_t 线程 ID,用来区分同进程下不同执行流;
- 寄存器上下文 程序运行时的通用寄存器、程序计数器等,线程切换时会保存 / 恢复这组寄存器数据,保证执行不会错乱;
- 独立栈空间 函数调用、局部变量、函数返回地址全部存放在线程私有栈,多个线程函数调用互不干扰;
- errno 全局错误标记 每个线程有独立的 errno 副本,一个线程函数报错修改 errno,不会影响其他线程的错误判断;
- 私有信号屏蔽字 每条线程可以单独设置要屏蔽的信号,线程间信号屏蔽规则互不干涉;
- 独立调度优先级 内核调度器会依据每条线程自身的优先级分配 CPU 时间片,同一进程内不同线程可设置不同优先级。
创建一个线程的代价远小于创建一个新进程,删除也是一致的
代码
线程创建
pthread_create

参数说明
pthread_t *thread:输出参数,创建成功后存入新线程 ID(你截图里打印的 tid)const pthread_attr_t *attr:线程属性,传nullptr使用默认属性void *(*start_routine)(void *):线程入口函数,返回void*、参数void*void *arg:传给线程函数的参数,任意类型指针
返回值
0:创建成功- 非 0:错误码(如内存不足、权限错误)




不是lwp
十六进制打印


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

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


新线程的tid


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

丰富一下


多个执行流进入函数----->重入
我们将print操作封装,发现线程都可以使用------代码是共享的


定义全局变量


让新线程对其进行++

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

以上证明多线程资源共享
代码异常


异常问题:任意线程异常奔溃,会导致整个进程挂掉
让线程一下子全部都创建出来

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


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

循环里
char threadname[64]是栈局部数组,每次循环覆盖内容; 创建子线程时直接传数组地址,子线程读取时数组内容早已被下一轮循环修改,线程 name 偶尔错乱。
这样会出现数据不一致的问题
除了上面这个可能,也会有下面这种情况
printf是行缓冲,但多线程并发调用时,一行打印会被其他线程打断穿插。 多个线程同时执行 printf,操作系统线程调度会随时切换线程,导致文字错位、顺序杂乱。