线程的控制

线程的创建:

线程创建函数: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。