(一)线程回收
(1)有返回值的回收:pthread_join();
(2)没有返回值的回收,设置线程的属性:pthread_detach();
pthread_self();
返回值:获得所在线程的线程号tid
pthread_detach(pthread_self()); //设置所在子线程的属性,自动回收释放的资源。
子线程如果没有被主线程回收,其不会像子进程那样变成僵尸进程,但是进程占用的资源是仍有的,因此需要对这部分资源进行回收。
(二)pthread_join函数(阻塞的)
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
回收函数pthread_join()是一个阻塞等待线程,直到线程结束的函数。
参数:
(1) thread:要回收的线程对象tid,此时传的是对象的值,不再是pthread_create()第一个参数传的是地址;
(2) retval:是一个指向 void * 指针 的指针。* retval是一个接收子线程的返回值。
返回值:
成功:返回0
失败:返回错误码errno
(三)结束当前的线程:pthread_exit()函数
#include <pthread.h>
void pthread_exit(void *retval);
(1)结束当前的线程;
(2)(void *) reval的值可以被其他线程通过pthread_join接收;
reval可以是任意类型:当为int 型式,可以把retval当成地址值传递参数。
(3)此子线程的私有资源被释放。
(四)取消线程
#include <pthread.h>
int pthread_cancel(pthread_t thread); //取消线程
void pthread_testcancel(void); //添加线程测试点
pthread_cancel(tid);放在主线程中,请求取消tid对象的线程。
因为有时候在子线程中,找不到可以让主线程中的pthread_cancel取消的信号点,
此时需要调用另外一个函数pthread_testcancel();设置测试点。
程序:
1 #include <stdio.h>
2 #include <string.h>
3 #include <pthread.h>
4 #include <unistd.h>
5
6 #define NUM 5
7
8 void * mypthread(void * arg)
9 {
10 int i;
11 int a = 1;
12
13 i = (int)arg;
14 printf("this is a my pthread, i = %d\n", i);
15
16 sleep(5);
17 //pthread_exit("hello world"); //retval传字符串
18 //pthread_exit((void *)a); //传数值,强转a为地址,不用取地址传递。
pthread_detach(pthread_self());//设置线程的自动回收释放的资源属性
19 return (void *)NULL;
20 }
21
22 int main(int argc, const char *argv[])
23 {
24 int i;
25 int ret;
26 void * retval;
27 pthread_t tid[NUM];
28
29 for(i = 0; i < NUM; i++)
30 {
31 printf("i = %d\n", i);
32 ret = pthread_create(&tid[i], NULL, mypthread, (void *)i);
33 if(ret != 0)
34 {
35 printf("%s\n", strerror(ret));
36 return(-1);
37 }
// pthread_detach();
38 }
39 /*
40 for(i = 0; i < NUM; i++)
41 {
42 pthread_join(tid[i], &retval);
43 printf("recv retval = %d\n", (int)retval);
44 }
*/
45 while(1)
46 {
47 sleep(1);
48 }
49 return 0;
50 }