①线程退出的方法:
1.创建线程时的tart_routine()函数内执行了return(),并且返回指定值。
2.线程调用 pthread_exit()
3.其他线程调用了pthread_cancel()函数取消了该线程(详见第8章)
4.线程函数执行完后自动返回(就算没有以上3中方法)
注意: 线程组中的任何一个线程调用了exit()函数,或者主线程在main()函数中执行了 return 语句,那么整个线程组内的所有线程都会终止。
②pthread_exit(void *value_ptr)
value_ptr: 存放线程的“临终遗言”,线程组内的其他线程可以通过调用pthread_join()函数接收这个地址,可以直接传递NULL指针
1.线程却调用pthread_exi 函数退出了那么主线程将进入僵尸状态.
③安全的传递线程退出的返回值
1.不能将遗言存放到线程的局部变量里,因为如果用户写的线程函数退出了,线程函数栈上的局部变量可能就不复存在了
2.如果是 int 型的变量,则可以使用“pthread_exit (( int* ) ret ); ”
3.使用全局变量返回
4.将返回值填入到用malloc()在堆上分配的空间里
5.使用字符串常量,如pthread_exit(“hello,world”)// 字符串常保存在今天存储区(数据段), 字符串数组变量保存在栈中
④注意:
1.子线程执行完毕后, 会自动退出线程, 不会陷入僵尸状态。但是资源任然在进程中没有得到释放, 并且这块资源并不会 复用。
2.子线程也可以return退出并返回给主线程参数
示例代码1: 子线程执行完毕后, 会自动退出线程, 不会陷入僵尸状态
// 子线程函数执行完毕后制动退出线程
void *start_routime1(void *arg)
{
printf("start_routime1\n");
getchar(); // 阻塞
printf("routime1 quit\n");
}
int main(int argc, char **argv)
{
pthread_t thid;
if(pthread_create(&thid, NULL, start_routime1, NULL))
perror("pthread_create err");
while(1)
sleep(1);
return 0;
}
/* 执行结果:
book@gui_hua_shu$ ./th
start_routime1
在另一个终端输入ps -eLf: 现在有两个线程
UID PID PPID LWP C NLWP STIME TTY TIME CMD
book 19555 18415 19555 0 2 15:57 pts/9 00:00:00 ./th
book 19555 18415 19556 0 2 15:57 pts/9 00:00:00 ./th
book@gui_hua_shu$ c
routime1 quit
在另一个终端输入ps -eLf: 现只有一个线程
UID PID PPID LWP C NLWP STIME TTY TIME CMD
book 19555 18415 19555 0 2 15:57 pts/9 00:00:00 ./th
*/
示例代码2: 主线程执行return后, 线程组会退出
// 只要就算子线程没有退出,
void *start_routime1(void *arg)
{
printf("start_routime1\n");
getchar(); // 阻塞
printf("routime1 quit\n");
}
int main(int argc, char **argv)
{
pthread_t thid;
if(pthread_create(&thid, NULL, start_routime1, NULL))
perror("pthread_create err");
sleep(2);
return 0;
}
/* 执行结果:
book@gui_hua_shu$ ./th
start_routime1
book@gui_hua_shu:$ ps
PID TTY TIME CMD
18415 pts/9 00:00:00 bash
19693 pts/9 00:00:00 ps
book@gui_hua_shu:$
*/
示例代码3: 主线程执行exit后, 线程组会退出
// 任意线程执行exit函数, 线程组都会退出
void *start_routime1(void *arg)
{
printf("start_routime1\n");
getchar(); // 阻塞
printf("routime1 quit\n");
exit(0);
}
int main(int argc, char **argv)
{
pthread_t thid;
if(pthread_create(&thid, NULL, start_routime1, NULL))
perror("pthread_create err");
while(1)
sleep(2);
return 0;
}
/* 执行结果:
book@gui_hua_shu$ ./th
start_routime1
UID PID PPID LWP C NLWP STIME TTY TIME CMD
book 19812 18415 19812 0 2 16:19 pts/9 00:00:00 ./th
book 19812 18415 19813 0 2 16:19 pts/9 00:00:00 ./th
c
routime1 quit
主线程和子线程都退出了
*/
示例代码4: 子线程使用return退出并返回给主线程参数
int ret = 888; // 不能为非静态局部变量(保存在栈中),线程退出后这个空间或被释放
// 子线程也可以return退出并返回给主线程参数
void *start_routime1(void *arg)
{
printf("start_routime1\n");
return (int *)&ret;
}
int main(int argc, char **argv)
{
pthread_t thid;
void *pret;
if(pthread_create(&thid, NULL, start_routime1, NULL))
perror("pthread_create err");
pthread_join(thid, &pret);
printf("routime1 return %d\n", *(int *)pret);
return 0;
}
/* 执行结果:
book@gui_hua_shu$ ./th
start_routime1
routime1 return 888
*/
示例代码5: 子线程使用pthread_exit退出并malooc变量返回给主线程参数
void *start_routime1(void *arg)
{
printf("start_routime1\n");
int *ret = malloc(4);
*ret = 123;
pthread_exit((void *)ret);
}
void *start_routime2(void *arg)
{
printf("start_routime2\n");
pthread_exit("aaaaaaaaaa");
}
int main(int argc, char **argv)
{
pthread_t thid,thid2;
void *pret;
void *pret2;
if(pthread_create(&thid, NULL, start_routime1, NULL))
perror("pthread_create err");
if(pthread_create(&thid2, NULL, start_routime2, NULL))
perror("pthread_create err");
pthread_join(thid, &pret);
printf("routime1 return: %d\n", *(int *)pret);
free(pret); /* 释放堆中的内存 */
pthread_join(thid2, &pret);
printf("routime2 return: %s\n", (char *)pret);
return 0;
}
/* 执行结果:
book@gui_hua_shu:$ ./th
start_routime1
start_routime2
routime1 return: 123
routime2 return: aaaaaaaaaa
*/