在Linux里面线程被称为轻量级线程,而线程的退出有以下几种方法:
- 线程调用return函数返回,但是在主线程里面不适用,因为主线程里面调用return函数相当于在主线程里面调用exit函数。
- 线程调用pthread_exit函数退出
- 线程调用pthread_cancel函数终止同一个进程里面的其他线程
在系统的角度来看待线程是没有具体的结构的,在系统的眼里只有进程。所以线程和进程一样,在执行的时候没有固定的先后顺序的,具体的和系统的调度方式有关。所以在创建进程之后需要对线程进行控制。
线程等待
int pthread_join(pthread_t thread,void** value_ptr);
thread:线程ID
value_ptr:指向一个指针,指针指向线程的返回值
调用pthread_join函数的时候,调用的线程将会挂起等待,直到指定的线程退出,并获取该线程的退出状态,回收线程的资源(类似于进程等待);
同样如果在线程退出的时候没有等待,那么该线程就会处于类似于僵尸进程的状态,造成内存泄漏。
在创建线程的时候应该在主线程里面等待每一个创建的线程,这样就可以避免内存泄漏的问题。
线程终止
int pthread_exit(void** value_ptr);
value_ptr:线程退出时候的退出码
注意:value_ptr指向的必须是全局的变量或者使用malloc函数申请的空间,因为在线程调用pthread_exit函数的时候线程已经退出,这时候栈资源会被释放。
int pthread_cancel(pthread_t thread);
thread:线程ID
是调用pthread_cancel函数的可以是同一进程里面的任意线程(包括需要取消的线程的本身),使用pthread_cancel函数时该线程的退出码是PTHREAD_CANCELED—->((void**)-1);
线程分离
在默认情况下创建的线程是可结合的,在线程退出后需要使用pthread_join来回收退出线程的资源。
如果不关系线程的退出状态,那么调用pthread_join操作便会是一种负担,这个时候可以使线程进行分离,当线程退出的时候就会自动的释放资源。
int pthread_detach(pthrad_t thread);
thread:线程ID
可以使同一个进程里面的线程对目标线程进行分离,也可以是线程自身分离。在线程分离之后该线程不能够被其他线程回收和终止,分离线程的资源由系统自动释放。
注:线程可结合和分离是互斥的,一个线程不能够既是可结合的有事分离的。
实例:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void* ret1;
void* ret2;
void* ret3;
void* pthread_run1(void*arg){
sleep(1);
printf("I`m first pthread\n");
int* p = malloc(sizeof(int));
*p = 1;
pthread_exit((void*)p);
}
void* pthread_run2(void* arg){
sleep(1);
printf("I`m second pthread\n");
int* p = malloc(sizeof(int));
*p = 2;
pthread_exit((void*)p);
}
void* pthread_run3(void* arg){
sleep(1);
printf("I`m three pthread\n");
int* p = malloc(sizeof(int));
*p = 3;
pthread_exit((void*)p);
}
int main(){
pthread_t tid1,tid2,tid3;
pthread_create(&tid1,NULL,pthread_run1,NULL);
pthread_create(&tid2,NULL,pthread_run2,NULL);
pthread_create(&tid3,NULL,pthread_run3,NULL);
pthread_join(tid1,&ret1);
pthread_join(tid2,&ret2);
pthread_join(tid3,&ret3);
printf("pthrad1 exit code :%d\n",*(int*)ret1);
printf("pthrad1 exit code :%d\n",*(int*)ret2);
printf("pthrad1 exit code :%d\n",*(int*)ret3);
return 0;
}