概念
- 书面 通常线程指的是共享相同地址空间的多个任务
- 人话 带有时间片的函数
特点
使用多线程的好处
- 大大提高了任务切换效率
- 避免了额外的TLB&cache的刷新
线程共享的资源
- 可执行指令
- 静态数据
- 进程中打开的文件描述符
- 当前的工作目录
- 用户ID
- 用户组ID
线程独占的资源
- 线程ID
- PC(程序计数器)和相关寄存器
- 堆栈
- 错误号(errno)
- 优先级
- 执行状态和属性
linux线程库
安装及更新
- sudo apt-get install manpages-posix-dev manpages-posix
pthread线程库提供了如下基本条件
- 创建线程
- 回收线程
- 结束线程
同步和互斥机制
- 信号量
- 互斥锁
- 条件变量
基本函数
创建线程 pthread_create
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*routine)(void *),void *arg);
//返回值:
成功返回0,失败返回错误码
//参数:
thread 线程对象
attr 线程属性,NULL代表默认属性
routine 线程执行的函数
arg 传递给routine的参数
回收线程 pthread_join
int pthread_join(pthread_t threa,void **retval);
//功能
调用线程阻塞直到thread结束
//返回值
成功返回0,失败时返回错误码
//参数
*retval接收线程thread的返回值
thread要收回的线程对象
结束线程 pthread_exit
void pthread_exit(void *retval);
//功能
结束当前线程,线程私有资源被释放
//参数
retval不能是局部变量
retval可被其他线程通过pthread_join获取
同步和互斥
同步机制
- 同步(synchronization)指的是多个任务按照约定的先后次序相互配合完成一件事情
- 由信号量来决定线程是继续运行还是阻塞等待
互斥机制
- 临界资源 一次只允许一个任务(进程、线程)访问资源
- 临界区 访问临界资源的代码
pthread_mutex互斥锁,就是互斥机制
线程实现同步互斥的方法
线程互斥锁
- 锁属于互斥机制
- 基本函数
- 初始化锁 pthread_mutex_init();
- 互斥锁上锁 pthread_mutex_lock();
- 判断互斥锁上锁 pthread_mutex_trylock();
- 互斥锁解锁 pthread_mutex_unlock();
- 消除互斥锁 pthread_mutex_destroy();
条件变量
属于同步机制
基本函数
- 初始化 pthread_cond_init();
- pthread_cond_init(条件变量ID,属性);
- 等待资源 pthread_cond_wait();
- pthread_cond_wait(条件变量ID,锁的ID);
- 必须搭配锁来使用
- 告知资源到达 pthread_cond_signal();
- 初始化 pthread_cond_init();
等待操作包含的几个步骤
- 解锁
- 进入等待状态
- 资源到达
- 加锁
信号量
概念
- 信号量代表某一类资源,其值表示系统中该资源的数量
- 信号量是一个受保护的变量
- 初始化
- P操作(申请资源)
- V操作(释放资源)
Posix信号量
- 无名信号量(基于内存的信号量)
P/V操作
- P(S)含义如下
- 如果信号量的值大于0,线程获得资源(信号量-1)且线程继续运行不会阻塞
- 如果信号量等于0,线程无法获得资源且阻塞在那里
- V(S)含义如下
- 线程释放资源(信号量+1)
- 如果有任务等待资源,则唤醒等待任务,让其继续运行。
- P(S)含义如下
进程和线程的不同点
\ | 进程 | 线程 |
---|---|---|
地址空间 | 独占 | 共享 |
通信 | 7中(Unix早期通信3种、System V 3种、套接字) | 信号量、互斥锁、条件变量 |
调度和切换 | 系统开销大,切换较慢 | 系统开销小,切换迅速 |
依赖性 | 相互独立 | 依赖于进程 |