POSIX线程 (3)

本文介绍了如何创建一个线程属性并设置为脱离状态,以此创建的线程在结束时不会等待父线程的合并。主线程通过标志检测子线程结束,展示了线程间共享变量的现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2011-11-06 wcdj
BLP 4th P.431

线程的属性


在多线程程序中,通常在程序退出之前用pthread_join对线程再次进行同步,目的是让线程向创建它的主线程返回数据。但是,在某些情况下,我们既不需要第二个线程向主线程返回信息,也不想让主线程等待它的结束。例如,假设我们在主线程继续为用户提供服务的同时创建了第二个线程,新线程的作用是将用户正在编辑的数据文件进行备份存储,在备份工作结束后,第二个线程就可以直接终止了,它没有必要再回到主线程中。

我们可以创建这一类型的线程,它们被称为“ 脱离线程”( detached thread)。可以通过修改线程的属性或调用pthread_detach的方法来创建它们。在这里主要介绍通过修改线程的属性的方法。

主要的函数:
#include <pthread.h>
(1) int pthread_attr_init(pthread_attr_t *attr);
返回值:成功返回0,失败返回错误代码。
(2) 回收函数 pthread_attr_destory, 目的是对属性对象进行清理和回收。一旦对象被回收了,除非它被重新初始化,否则就不能被再次使用。
(3) 初始化一个线程属性对象后,可以调用许多其他的函数来设置不同的属性行为。(完整的函数列表见手册页,通常位于pthread.h条目下)。可以使用的线程属性非常多,但幸运的是,通常不需要设置太多属性就可以让程序正常工作。

一些主要的 属性介绍如下:
[1] detachedstate
这个属性允许我们无需对线程进行重新合并。与大多数_set类函数一样,它以一个属性指针和一个标志为参数来确定需要的状态。pthread_attr_setdetachstate函数可能用到的两个标志分别是:PTHREAD_CREATE_JOINABLE 和 PTHREAD_CREATE_DETACHED。这个属性的默认标志是 PTHREAD_CREATE_JOINABLE,所以可以允许两个线程重新合并。如果标志设置为 PTHREAD_CREATE_DETACHED,就不能调用 pthread_join来获得另一个线程的退出状态。
[2] schedpolicy
这个属性控制线程的调度方式。它的取值可以是 SCHED_OTHER、SCHED_RP 和 SCHED_FIFO。这个属性的默认值为 SCHED_OTHER。另外两种调度方式只能用于以超级用户权限运行的进程,因为它们都具备实时调度的功能,但在行为上略有区别。SCHED_RP 使用循环(round-robin)调度机制,而SCHED_FIFO 使用“先进先出”策略。

例子:设置脱离状态属性

首先创建一个线程属性,将其设置为脱离状态,然后用这个属性创建一个线程。子线程结束时,它照常调用pthread_exit,但这次,原先的线程不再等待与它创建的子线程重新合并。主线程通过一个简单的 thread_finished 标志来检测子线程是否已经结束,并显示线程之间仍然共享着变量。


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void *thread_function(void *arg);

char msg[] = "hello, wcdj!";
int thread_finished = 0;

int main()
{
	int res;
	pthread_t a_thread;
	pthread_attr_t thread_attr;

	res = pthread_attr_init(&thread_attr);
	if (res != 0)
	{
		perror("Attribute creation failed");
		exit(EXIT_FAILURE);
	}

	res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
	if (res != 0)
	{
		perror("Setting detached attribute failed");
		exit(EXIT_FAILURE);
	}

	res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)msg);
	if (res != 0)
	{
		perror("Thread creation failed");
		exit(EXIT_FAILURE);
	}


	(void)pthread_attr_destroy(&thread_attr);// free

	while(!thread_finished)
	{
		printf("Waiting for thread to say it's finished...\n");
		sleep(1);// sleep 1 second
	}

	printf("Other thread finished, bye!\n");
	exit(EXIT_SUCCESS);
}


void *thread_function(void *arg)
{
	printf("thread_function is running. Argument was %s\n", (char *)arg);
	sleep(4);// sleep 4 seconds
	printf("Second thread setting finished flag, and exiting now\n");
	thread_finished = 1;// flag
	pthread_exit(NULL);
}

/*
gerryyang@wcdj:~/test> gcc -D_REENTRANT -o thread5 thread5.c -lpthread
gerryyang@wcdj:~/test> ./thread5 
Waiting for thread to say it's finished...
thread_function is running. Argument was hello, wcdj!
Waiting for thread to say it's finished...
Waiting for thread to say it's finished...
Waiting for thread to say it's finished...
Second thread setting finished flag, and exiting now
Other thread finished, bye!
gerryyang@wcdj:~/test> 
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值