多线程编程
线程特性
线程—进程
- 线程之间能够方便,快速的共享信息,但注意同步
- 创建线程比创建进程快的多
线程的数据类型
数据类型 | 描述 |
---|---|
pthread_t | 线程ID |
pthread_mutex_t | 互斥对象 |
pthread_mutexattr_t | 互斥属性对象 |
pthread_cond_t | 条件变量 |
pthread_condattr_t | 条件变量的属性对象 |
pthread_key_t | 线程特有的数据键 |
pthread_attr_t | 线程的属性对象 |
以上数据结构不能直接通过==
来判断是否相等
线程相关函数
创建进程
#include<pthread.h>
int pthread_create(pthread_t * thread,const pthread_attr_t* attr,void*(*start)(void*),void *arg);
//Return 0 success,or a positive error number on error
Tips
- 线程启动后,会从start函数开始执行
- 对于start返回值要小心,
PTHREAD_CANCELED
是一有一个整形实现的,所以要避免返回值相同
终止线程
线程终止的方式
- 线程start函数
return
返回 - 线程调用
pthread_exit()
- 调用
pthread_cancel()
取消线程 - 任意线程调用了
exit()
,或者主线程执行了return
,会导致所以线立即终止。
pthread_exit()
#include<pthread.h>
void pthread_exit(void * retval);
Tips
- 与return 不同的是
pthread_exit()
可以在其他函数中中调用 - retval说指向的空间不应该在线程中,因为线程返回后,线程栈也有可能被收回
- 主线程调用
pthread_exit()
并不会导致其他线程结束
线程ID
获取自身线程ID
#include<pthread.h>
pthread_t pthread_self(void);
判断两个线程ID是否相同
#include<pathread.h>
int pthread_equal(pthread_t t1,pthread_t t2);
连接线程
#include<pthread.h>
int pthread_join(pthread_t thread,void **retval);
//retval非空的话保存线程返回值
//return 0 on success,or a positive error number on number
TIPS
- 若
pthread_join
传入放一个已经连接过的线程,会导致无法预知的行为,因为这个线程的ID也许会被其他线程使用 - 线程之间是对等的,所以
pthrea_join
中的线程ID可以是任何可行的线程 - 一个线程不能被多个线程等待,也就是说对一个线程只能调用一次
pthread_join
线程的分离
#include<pthread.h>
int pthread_detach(pthread_t thread);
//return 0 on success,or a positive error number on number
- 默认线程是joinable,也就是说必须需要有线程调用
pthread_join
来清理他,不然会创建僵尸线程 pthread_detach()
可以使线程结束后自动由系统清理- 调用
pthread_detach()
之后就不能再调用pthread_join()
获取状态。