一、概念:
线程指的是共享相同地址空间的多个任务
是一个轻量级的进程,为了提高系统的性能引入线程,线程和进程都参与统一的调度
在同一个进程中创建的线程共享该进程的地址空间
有一个工厂,工厂里面有一个车间,车间里面有工人
有一个系统,系统里面有一个进程,进程里面有线程
供不应求:1.建一个车间,招一个工人
2.招工人
二、特点:
1)由于进程的地址空间是私有的,因此在进程间上下文切换时,系统开销比较大
2)为了提高系统的性能,许多操作系统规范里引入了轻量级进程的概念,也被称为线程
3)在同一个进程中创建的线程共享该进程的地址空间
4)Linux里同样用task_struct来描述一个线程。线程和进程都参与统一的调度
三、优点:
1)使用多线程的好处大大提高了任务切换的效率
2)多线程通信简单,可以通过全局变量
四、线程和进程的区别:
1)进程间相互独立,而同一个进程内的线程间共享进程内所有的资源
2)多线程间通信简单,但是需要对临界资源进行互斥与同步操作,多进程间通信较难
3)多线程安全性差,因为其中一个线程崩溃可能会对其他线程造成影响,多进程间相互独立,安全性高。
共性:都为操作系统提供了并发执行能力
不同点:调度和资源:线程是系统调度的最小单位,进程是资源分配的最小单位
地址空间方面:同一个进程创建的多个线程共享进程的资源;进程的地址空 间相互独立
通信方面:线程通信相对简单,只需要通过全局变量可以实现,但是需要考虑临界资
源访问的问题;进程通信比较复杂,需要借助进程间的通信机制(借助3g-4g内核空间)
安全性方面:线程安全性差一些,当进程结束时会导致所有线程退出;进程相对安全
临界资源:一次仅允许一个进程/线程访问的资源
临界区:访问临界资源的代码区域
安装:第三方库的man手册
sudo apt-get install manpages-posix manpages-posix-dev
man pthread_create
- 线程资源
共享的资源:可执行的指令、静态数据、进程中打开的文件描述符、信号处理函数、当前工作目录、用户ID、用户组ID
- 私有的资源:线程ID (TID)、PC(程序计数器)和相关寄存器、堆栈、错误号 (errno)、信号掩码和优先级、执行状态和属性
五、线程函数
1、pthread_create
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
功能:创建一个线程
参数:
(1)tidp:事先创建好的pthread_t类型的参数。成功时tidp指向的内存单元被设置为新创建线程的线程ID。
(2)attr:用于定制各种不同的线程属性。APUE的12.3节讨论了线程属性。通常直接设为NULL。
(3)start_rtn:新创建线程从此函数开始运行。无参数是arg设为NULL即可。
(4)arg:start_rtn函数的参数。无参数时设为NULL即可。有参数时输入参数的地址。当多于一个参数时应当使用结构体传入。
返回值:成功返回0,失败非0.
进程退出所有线程都退出
向函数线程传递参数
2、pthread_exit 退出线程
#include <pthread.h>
void pthread_exit(void *retval);
功能:退出线程,由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放,
参数:retval:线程退出时返回的值(通常为NULL)
返回值:成功 : 0
失败:errno
pthread_exit() 函数不能返回一个指向局部数据的指针,否则很可能使程序运行结果出错甚至崩溃。
只退出某一个线程
3、回收线程 pthread_join
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
功能:用于阻塞等待一个指定的线程结束
参数:thread:创建的线程对象,线程标识符,即线程ID,标识唯一线程
retval:指针*retval指向线程返回的参数,用户定义的指针,用来存储被等待线程的返回值。
返回值:成功 : 0
失败:errno
补充:空类型二级指针不兼容其他类型二级指针,空类型一级指针兼容其他类型一级指针
注意函数内部的局部变量会随函数结束而销毁空间,用static修饰放到静态区,不随 函 数结束而销毁。
线程结束返回参数
4、获取线程tid pthread_self
#include <pthread.h>
pthread_t pthread_self(void);
功能:获取线程tid
参数:无
返回值:成功得到线程tid,失败 错误码
- pthread_cancal在线程中发送关闭指定线程的请求
线程退出pthread_exit只能终止当前线程,也就是哪个线程调用了pthread_exit,哪个线程就会退出;但是线程取消pthread_cancel ,不光可以终止自己,还可以终止其他线程。
#include <pthread.h>
int pthread_cancel(pthread_t thread);
功能: 在线程中发送关闭指定线程的请求
参数:thread 要关闭的线程号
返回值: 成功: 0
失败: 负数,更新 errno
6、将线程设置为游离态pthread_detach
#include <pthread.h>
int pthread_detach(pthread_t thread);
功能:从状态上实现线程分离,将线程设置为detach(游离态),线程退出由系统自动 回收线程资源,
无需使用pthread_join
参数:要操作的线程id
返回值:成功 0,失败 错误码
线程分离状态:
指定该状态,线程主动与主控线程断开关系。线程结束后(不会产生僵尸线程),其退出状态不由其他线程获取,而直接自己自动释放(自己清理掉PCB的残留资源)进程结束后,线程也会结束。
与pthread_join不同的是不阻塞等待,子线程结束后自动回收,不影响我主线程的执行。datach不能接受退出进程的返回值