一.线程(执行流)
1.概念
- 线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
2.线程,进程的区别
- 操作系统的最小调度单位:线程
- 操作系统的进程资源分配的基本单位:进程
1.构成
- 进程由3部分构成 :进程控制块(pcb), 程序段,数据段。
- 线程是进程的一个实体,线程自己不具有系统资源,只拥有一点在运行中必不可少的资源。线程与同属一个进程的其他线程共享进程拥有的所有资源。
2.关系
- 一个程序至少有一个进程,一个进程至少有一个线程。通常将该线程称为主线程。
- 一个线程可以创建和撤销另一个线程,同一进程中多个线程之间可以并发执行。
- 进程可以独立运行,但线程不能独立执行,必须依存在进程中执行。
- 线程自己不具有系统资源,线程与同属一个进程的其他线程共享进程拥有的所有资源。【根本区别】
3.进程与程序的区别
- 程序:是一个在时间上按严格次序顺序执行的操作序列。
- 进程:是一个程序关于某个数据集的一次运行,进程是运行中的程序,是程序的一次运行活动。即进程 = 程序段 + 数据段 + PCB
- 进程是一个动态的概念,而程序是一个静态的概念。因此,进程具有动态性和并发性。
- 进程和程序不是一 一对应的关系,一个程序执行在不同的数据集,就成为不同的进程,可以用进程控制块(PCB)来唯一地标识每一个进程。所以,一个进程有唯一与之对应的程序。而一个程序有可能没有与之对应的进程(没执行),也有可能有多个进程与之对应。 即,进程 --> 程序(1对1),程序–>进程(1对多)
4.线程其他知识
- 接口均为库函数,操作系统没有提供,
- 所以—》linux操作系统将线程认为轻量级进程!
1.线程号
- 当进程仅有一个线程时,进程号(tgid)==线程号(pid)
- 当进程有多个并行线程时,线程号各不相同(tgid)
2.线程优点
- 提高程序的并发性,占用多个cpu,执行任务。
- 开销小,不用重新分配内存
- 通信和共享数据方便
3.线程缺点
- 降低程序健壮性
- 代码编写难度提高
- 缺乏访问控制
- 不同执行流的执行时序问题
- 性能损失(不断切换执行流)
4.线程的独有资源
- 线程号(tid)
- 一组寄存器
- 信号屏蔽字
- 优先级调度
- errno
- 栈
5.线程共享资源
- 进程的虚拟地址空间,代码段,数据段
- 文件描述符表
- 当前进程工作路径
- 用户组及用户id
5.创建线程
pthread_creat(pthread_t *,NULL,ThreadStart,NULL)
第一个参数:线程标识符(线程首地址)
第二个参数:pthread_attr_t:线程属性
第三个参数:线程入口函数
void* (* start_routinue)(void*)
第四个参数:传给线程入口函数的参数
6.终止线程
#include <pthread.h>
void pthread_exit(void *retval);
void *retval:线程退出时传递出的参数,可以是退出值或地址,如是地址时,不能是线程内部申请的局部地址。 可以为NULL
在进程内某个线程可以取消另一个线程(或者自己)。
#include <pthread.h>
int pthread_cancel(pthread_t thread);
- 获取自己的线程号
pthread_t pthread_self(void);
7.线程等待
- 默认的线程创建时属性为joinable,当线程退出时必须其他线程回收此线程资源,否则不会被释放,造成内存泄漏。
- 线程等待:为了防止线程退出时的资源泄露。
int pthread_join(pthread_t thread, void **thread_return);
pthread_t thread:回收线程的tid
void **thread_return:接收退出线程传递出的返回值
以不同的方法结束线程会返回不同的值:
thread线程通过return返回:
-
retval所指向的单元里存放的是thread线程函数的返回值
-
调用pthread_cancel异常终止掉:retval所指向的单元里存放的是常数PTHREAD_CANCELED+
-
thread线程是自己调用pthread_exit终止的:retval所指向的单元存放的是传给pthread_exit的参数
-
对thread线程的终止状态不感兴趣,可以传NULL给retval参数
8.线程分离
- 将线程设置为分离属性,退出时不需要其他线程回收资源,也不会造成资源泄露
int pthread_detach(pthread_t *thread);