1.线程的本质
线程与进程的区别:线程大家可以简单理解为一个轻量级的进程,线程共享了栈和堆(变量),没有复制 0-3 G 的进程空间,
但线程会有自己的工作空间,会有自己的 pcb 块。跟 Java 是类似的。
- linux线程执行和windows不同,pthread有两种状态
joinable
状态和unjoinable
状态,
如果线程是joinable
状态,当线程函数自己返回退出时或pthread_exit
时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join
之后这些资源才会被释放。
若是unjoinable
状态的线程,这些资源在线程函数退出时或pthread_exit时
自动会被释放。 unjoinable
属性可以在pthread_create时指定
,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态
,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.- 其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦。
2.创建线程
pthread_create(&tid,NULL,thread_run,NULL);
1 |
|
3.退出线程
pthread_exit(-1);
1 |
|
4.回收线程
pthread_join(tid,&retval); // retval = 0代表回收成功,-1 代表线程已经退出了
pthread_join()即是子线程合入主线程,主线程阻塞等待子线程结束
,然后回收子线程资源。
pthread_join()函数,以阻塞的方式
等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回
。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
一般情况下需要回收线程,retval 用来接收线程的返回值,tid 是线程的id,该方法会阻塞等待
什么情况下不需要回收呢?除非调用了分离线程
1 |
|
5.杀死(取消)线程
pthread_cancel(tid);
// 取消线程需要有函数进入内核,也就是说需要调用系统函数
1 |
|
6.分离线程
pthread_detach(tid);使线程ID为tid的线程处于分离状态,一旦线程处于分离状态,该线程终止时底 层资源立即被回收
分离线程之后是当线程执行完毕或者pthread_exit
后,残留在线程中的资源会自动回收,也就是说线程需要回收,有两种方式一种是 join 一种是 detach 分离。
该函数不会阻塞父线程。pthread_detach(tid);函数用于只是应用程序在线程tid终止时回收其存储空间。如果tid尚未终止,pthread_detach()不会终止该线程。
1 |
|
7.线程同步
pthread_mutex_t mutex
- 加锁:
pthread_mutex_lock(&mutex);
- 解锁:
pthread_mutex_unlock(&mutex);
- 销毁锁:
pthread_mutex_destroy(&mutex);
1 |
|