Skip to content

LV020-线程分离

本文主要是线程——线程分离的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

一、什么是线程分离

默认情况下,当线程终止时,其它线程可以通过调用 pthread_join() 获取其返回状态、回收线程资源。可是有时候,我们并不关心线程的返回状态,只是希望系统在线程终止时能够自动回收线程资源并将其移除。在这种情况下,可以调用 pthread_detach() 将指定线程进行分离,也就是分离线程。分离线程后,线程结束也不会产生僵尸线程。

二、分离函数

1. pthread_detach()

1.1 函数说明

在 linux 下可以使用 man pthread_detach 命令查看该函数的帮助手册。

c
/* Compile and link with -pthread. */
#include <pthread.h>
int pthread_detach(pthread_t thread);

函数说明】该函数将指定线程进行分离。

函数参数

  • thread : pthread_t 类型,参数 thread 指定需要分离的线程的线程 ID 。

返回值】 int 类型,成功返回 0 ,失败将返回错误码。

使用格式】一般情况下基本使用格式如下:

c
/* 需要包含的头文件 */
#include <pthread.h>

/* 至少应该有的语句 */
pthread_cancel(tid);
/* 或者在自己的线程中分离自己 */
pthread_detach(pthread_self());

注意

(1)一个线程既可以将另一个线程分离,同时也可以将自己分离。

(2)设置了线程分离之后,就无法通过 pthread_join() 来获取已结束线程的信息了, pthread_join() 函数将会返回错误信息。

1.2 使用实例

c
#include <stdio.h>
#include <pthread.h>/* pthread_create pthread_exit pthread_self pthread_join pthread_detach*/
#include <unistd.h> /* sleep */
#include <string.h> /* strerror */

void *threadDetach(void *arg);


int main(int argc, char *argv[])
{
	int ret;
	pthread_t tid;
	/* 1. 创建一个线程 */
	ret = pthread_create(&tid, NULL, threadDetach, NULL);
	printf("This is main thread,ret=%d,tid=%lu\n", ret, tid);

	/* 2. 主线程分离子线程或者在子线程中分离自己 */
	// pthread_detach(tid);
	sleep(5);
	/* 3. 分离后进行回收,若分离成功,则会出错 */
	ret = pthread_join(tid, NULL);
	if(ret != 0)
		printf("pthread_join error: %s\n", strerror(ret));

	return 0;
}

void *threadDetach(void *arg)
{
	/* 自行分离 */
	pthread_detach(pthread_self());

	printf("This is a thread test! pid=%d,tid=%lu\n", getpid(), pthread_self());
	sleep(3);
	pthread_exit("thread return!");
}

在终端执行以下命令编译程序:

shell
gcc test.c -Wall -l pthread # 生成可执行文件 a.out 
./a.out # 执行可执行程序

然后,终端会有以下信息显示:

shell
This is main thread,ret=0,tid=139858080994880
This is a thread test! pid=4353,tid=139858080994880
pthread_join error: Invalid argument

三、分离状态属性

除了使用 pthread_detach 函数来设置线程分离,还可以通过设置创建线程时的属性来达到线程分离的效果,详情可以查看上一节的笔记。

四、内存演示

与前边的线程回收一节中的内存演示步骤及判断方式一样。不过此处我有一点点的疑问,就是我使用 Ubuntu21.04 的 64 位时候,内存似乎还变大了,但是我使用 Ubuntu14.04 的 32 位版本就是正常的,这个原因嘛,我还没找到,先这样记着,后边搞明白了再补充。

c
#include <stdio.h>
#include <pthread.h>/* pthread_create pthread_exit pthread_self pthread_join pthread_detach*/
#include <unistd.h> /* sleep */

#define pthreadDetach

void *threadDetach(void *arg);

int main(int argc, char *argv[])
{
	int ret;
	int i = 0;
	pthread_t tid[100];
	/* 1. 创建线程 */
	for(i=0; i<100; i++)
	{
		ret = pthread_create(&tid[i], NULL, threadDetach, (void *)i);
		printf("This is [%d] thread,ret=%d,tid=%lu\n",i, ret, tid[i]);
	}

	while(1)
	{
		sleep(1);
	}
	return 0;
}

void *threadDetach(void *arg)
{
#ifdef pthreadDetach
	/* 自行分离 */
	pthread_detach(pthread_self());
#endif
	printf("This is [%d] thread test! pid=%d,tid=%lu\n", (int)arg, getpid(), pthread_self());
	sleep(25);
	pthread_exit("thread return!");
}