一、基础 名词 & 概念
1、可执行程序
(可执行程序文件是一个静态的概念) C/C++源文件经过编译器(编译+链接)处理后,会产生可执行程序文件,不同系统有不同格式,比如Linux系统的ELF格式、Windows系统的EXE格式
2、进程是什么
可执行程序在操作系统上的一次执行对应一个进程,(进程是一个动态的概念)【 进程是资源分配的基本单位 】
进程是执行中的程序。同一份可执行文件执行多次,会产生多个进程,这跟一个类可以创建多个实例一样
3、线程是什么
一个进程内的多个线程代表着多个执行流,这些线程以并发模式独立执行
【 操作系统中,被调度执行的最小单位是线程 】
进程是通过共享存储空间对用户呈现的逻辑概念; 同一进程内的 多个线程 共享 地址空间和文件描述符
共享地址空间意味着 == 进程的代码(函数)区域、全局变量、堆、栈 都被进程内的 多线程 共享
其实 : Linux内核认为根本没有所谓的进程和线程的概念,只有COE(Linux称之为任务),不同的COE可以相互共享一些状态,通过此类共享向上构建起进程和线程的概念
进程和线程都是一回事:一个执行上下文(context of execution)== COE
4、LWP
LWP 本质上是 线程,是操作系统中由内核负责调度的一种执行单元
LWP通常指的是由操作系统内核调度的线程(即内核级线程)。这种定义明确区分了传统的进程(进程可以包含多个LWP,即线程)和线程,并且强调了共享资源的特点
线程就是轻量级进程
所有的线程都当作进程来实现, 因此线程和进程都是用task_struct来描述的。这一点通过/proc文件系统也能看出端倪,线程和进程拥有比较平等的地位。
对于多线程来说,原本的进程称为主线程,它们在一起组成一个线程组
5、协程
协程是 用户态的多执行流 - 是仅在用户态的概念 , 上下文切换成本比线程更低
6、线程私有数据
只有成员变量是私有的,【是吗】 还有 thread_local 异步情况下可以 InheritableThreadLocal 使用这个)
7、thread_local
todo待补充
8、阻塞和非阻塞
线程阻塞的原因有很多种,比如:
- 线程因为acquire某个锁而被操作系统挂起,如果acquire睡眠锁失败,线程会让出CPU,操作系统会调度另一个可运行线程到该CPU上执行,被调度走的线程会被加入等待队列,进入睡眠状态。 【复习 sleep 和 wait 】
- 线程调用了某个阻塞系统调用而等待,比如从没有数据到来的套接字上读数据,从空的消息队列里读消息 【比如接口--超时】
- 线程在循环里紧凑的执行测试&设置指令并一直没有成功,虽然线程还在CPU上执行,但它只是忙等(相当于白白浪费CPU),后面的指令没法执行,逻辑同样无法推进 【空循环 / 忙等 】
阻塞系统调用: 如果某个系统调用或者编程接口有可能导致线程阻塞 --迟迟拿不到响应
非阻塞调用 : 调用非阻塞的函数不会陷入阻塞,如果请求的资源不能得到满足,它会立即返回 并通过返回值或错误码报告原因,调用的地方可以选择重试或者返回