线程的退出

①线程退出的方法:
    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
*/

 

你可能感兴趣的:(第7章,理解Linux线程(1))