线程:
1.概念
线程是一个轻量级的进程
特点:
(1)线程位于进程空间的内部
(2)线程栈空间独立,数据区,文本区,堆区在进程中共享
进程与线程的区别:
(1)进程是操作系统资源分配的最小单元
(2)线程是CPU任务调度的最小单元
2.线程创建
在进程空间内部创建独立的栈空间
栈:独立 (局部变量)
堆区:共享 (malloc空间)
数据区:共享 (全局变量/静态变量)
文本区:共享 (代码)
3.线程调度:
和进程调度一样,宏观并行,微观串行
4.线程资源回收:
线程执行结束后,需要回收线程空间
5.多进程和多线程的优缺点:
(1)效率:
线程 > 进程
CPU在多线程间切换,是在同一进程空间(0 - 4G虚拟内存空间)内切换(因此也就没有保护现场和回复现场的操作)
CPU在多进程间切换,是在不同的进程空间切换
(2)多任务通信机制:
线程 > 进程
线程可以使用全局变量传递数据
进程没有共享区域,必须使用第三方对象来完成通信
(3)通信实现:
进程 > 线程
进程空间独立,通信时不需要考虑资源竞争问题
线程空间共享,通信时可能会引发资源竞争,需要加入互斥锁实现通信
(4)安全:
进程 > 线程
一个进程异常结束,不会影响其余进程
一个线程异常结束,会使进程结束,进程内其余线程也会结束
6.线程相关函数接口:
进程相关接口:fork exit wait
(1)pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
功能:创建一个线程
参数:
thread:存放线程ID空间首地址
attr:线程属性
start_routine:线程函数入口
arg:线程函数传参(如果想传入多个参数,那么可以选择传入结构体)
返回值:
成功返回0
失败返回错误码
编译时链接线程库
gcc filename.c -lpthread
pthread_self();函数可以用来获得线程ID,打印用%#x来打印;%x表示十六进制输出,#表示在打印的时候前面加上0x;
(2)pthread_exit
void pthread_exit(void *retval);
功能:让调用函数的线程结束
参数:
retval:线程结束时返回的值
返回值: 缺省
(3)pthread_join
int pthread_join(pthread_t thread, void **retval);
功能: 回收线程空间
参数:thread:线程ID
retval:存放线程退出状态值空间首地址(也就是pthread_exit的参数)
返回值:
成功返回0
失败返回错误码
注意:
(1)pthread_join具有阻塞功能
(2)pthread_join回收线程空间
(3)可以实现多个任务的同步
重点:循环创建多个线程的模型(注意线程回收的先后顺序,所以要用到线程的分离属性)
7.线程分离属性:
线程结束自动被操作系统回收空间
(1)pthread_attr_init
int pthread_attr_init(pthread_attr_t *attr);
功能:线程属性的初始化
参数:attr:线程属性变量空间首地址
返回值:
成功返回0
失败返回非0
(2)pthread_attr_setdetachstate
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
功能: 设置线程属性
参数:
attr:线程属性变量的首地址
detachstate:设置的属性
PTHREAD_CREATE_DETACHED 分离属性
PTHREAD_CREATE_JOINABLE 加入属性(阻塞属性) 默认
返回值:
成功返回0
失败返回非0
(3)pthread_attr_destroy
int pthread_attr_destroy(pthread_attr_t *attr);
功能: 线程属性销毁
参数: attr:线程属性变量空间首地址
返回值:
成功返回0
失败返回非0
特点:
(1)不需要调用pthread_join回收线程空间,线程结束系统自动回收空间
(2)多线程回收线程空间时多使用分离属性
(3)无法回收到线程结束的状态值
(4)进程无法与线程结束时刻同步(可以用全局变量弥补这个缺陷)