线程的控制
线程的创建:
线程创建函数:int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine(void*),void *arg);
返回值:成功返回0,失败返回错误号。
在一个线程中调用pthread_create()创建新的线程后,当前线程从pthread_create()返回继续往下执行,而新的线程所执行的代码由我们传给pthread_create()的函数指针star_routine决定。pthread_create成功返回后,新创建的线程id被填写到thread参数所指向的内存单元。线程id的类型是thread_t,它只在当前进程中保证是唯一的,在不同的系统中thread_t这个类型有不同的实现,它可能是一个整数值,也可能是一个结构体,也可能是一个地址,用pthread_self()可获得当前线程id。
如果任意一个线程调用了exit或_exit,则整个进程的所有线程都终止。
线程的终止:
有以下三种方法终止线程:
从线程函数return,这种方法对主线程不适用,从main函数return相当于调用exit;
一个线程可以调用pthread_cancel终止统一进程中的另一个线程;
程可以调用pthread_exit终自己;
下面我们看一段代码,看看这3中方法的区别:
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
void *thread1(void *arg)
{
printf("thread 1 returning....\n");
return (void*)1;
}
void *thread2(void *arg)
{
printf("thread 1 exiting....\n");
pthread_exit((void*)2);
}
void *thread3(void *arg)
{
while(1)
{
printf("thread 3 is runing,wait to bu cancel...\n");
sleep(1);
}
return NULL;
}
int main()
{
pthread_t tid;
void *val;
pthread_create(&tid,NULL,thread1,NULL);
pthread_join(tid,&val);
printf("thread return,thread id is:%u,return code is:%d\n",tid,(int)val);
pthread_create(&tid,NULL,thread2,NULL);
pthread_join(tid,&val);
printf("thread exit,thread id is:%u,exit code is:%d\n",tid,(int)val);
pthread_create(&tid,NULL,thread3,NULL);
sleep(3);
pthread_cancel(tid);
pthread_join(tid,&val);
printf("thread return,thread id is:%u,return code is:%d\n",tid,(int)val);
return 0;
}
运行结果如下:
一般情况下,线程终止后,其状态一直保留到其他线程调用pthread_join获取它的状态为止,但是线程也可以被置为detach状态,这样的线程一旦终止,就立刻回收它所占有的所有资源,而不保留终止状态,不能对一个处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL,对一个尚未detach的线程调用pthread_join或pthread_detach都可以把该线程置为detach状态。也就是说不能对一个线程调用两次pthread_join 或者已经对一个线程调用了pthread_detach,就不能再调用pthread_join了。
线程分离
在任何一个时间点上,线程是可结合的或者是可分离的,一个可结合的线程能够被其他线程收回其资源和杀死,在被其他线程收回之前,它的存储资源是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,他的存储器资源在它终止时由系统自动释放。
默认情况下,线程被创建成可结合的,为了避免存储器泄露,每个可结合线程要么被显示的回收,要么调用pthread_detach函数被分离。
由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,我们并不希望如此。我们这时可以在子线程代码中加入pthread_detach(pthread_self())或者父线程调用pthread_detach(tid).这将子线程的状态设置为分离的,该线程运行结束后会自动释放所有资源。
下面我们看一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
void *thread(void *arg)
{
pthread_detach(pthread_self());
printf("thread 1 returning....\n");
return NULL;
}
int main()
{
pthread_t tid;
int ret=pthread_create(&tid,NULL,thread,NULL);
if(ret!=0)
{
printf("create thread error,info is :%s\n",strerror(ret));
}
sleep(1);
if(0==pthread_join(tid,NULL))
{
printf("thread wait success\n");
}
else
{
printf("thread wait failed\n");
}
return 0;
}
运行结果:
从结果可以看到,我们在子线程里面用了pthread_detach,在主线程里面又用了pthread_join,所以会wait failed。