关闭

linux程序设计——线程的属性(第十二章)

321人阅读 评论(0) 收藏 举报
分类:

12.6    线程的属性

在前面的所有程序示例中,都在程序退出之前用pthread_join对线程再次进行同步,如果想让线程向创建它的线程返回数据就需要这样做.但有时,也有这种情况,既不需要第二个线程向主线程返回信息,也不想让主线程等待它的结束.
假设在主线程继续为用户提供服务的同时创建了第二个线程,新线程的作用是将用户正在编辑的数据文件进行备份存储.备份工作结束后,第二个线程就可以直接终止了,它没有必要再回到主线程中.
可以创建这一类型的线程,它们被称为脱离线程(detached thread).可以通过修改线程属性或调用pthread_detach的方法来创建它们
.这节是介绍线程的属性,因此在这里就使用修改线程属性的方法.
需要用到的最重要的函数是pthread_attr_init,它作用是初始化一个线程属性对象.
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
还有一个回收函数pthread_attr_destroy,它的目的是对属性对象进行清理和回收.一旦对象被回收了,除非它被重新初始化,否则就不能被再次利用.
初始化一个线程属性对象后,可以调用许多其他的函数来设置不同的属性行为.
常见的属性如下:
detachedstate:这个属性允许对线程进行重新合并.它以一个属性指针和一个标志为参数来确定需要的状态,默认标志值为PTHREAD_CREATE_JOINABLE允许两个线程重新合并,另一个标志PTHREAD_CREATE_DETACHED不允许调用pthread_join来获得另一个线程的退出状态.
schedpolicy:这个属性控制线程的调度方式.它的取值可以是SHED_OTHER,SCHED_RP和SCHED_FIFO
schedparam:这个属性是和schedpolicy属性结合使用的,它可以对SCHED_OTHER策略运行的线程的调度进行控制
inheritsched:这个属性可以取PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED.前者表示调度由属性明确地设置,后者表示新线程将沿用其创建者所使用的参数.
scope:这个属性控制一个线程调度的计算方式.
stacksize:这个属性控制线程创建的栈大小,单位为字节.

1.设置脱离状态属性

编写脱离线程示例程序thread5.c.创建一个线程属性,将其设置为脱离状态,然后用这个属性创建一个线程.子线程结束时,它照常调用pthread_exit,但是这次,原来的线程不再等待它创建的子线程重新合并.主线程通过一个简单的thread_finished标志来检测子线程是否已经结束,并线程线程之间仍然共享着变量.
/*************************************************************************
 > File Name:    thread5.c
 > Description:  thread5.c程序创建一个线程属性thread_attr,并将其设置为脱离状态,然后创建一个新线程,设置属性为thread_attr.
 > Author:       Liubingbing
 > Created Time: 2015年07月06日 星期一 20时36分36秒
 > Other:        thread5.c程序与之前程序的不同在于,原来的线程不再等待与它创建的新线程合并.主线程通过thread_finish标志来检测新线程是否结束.
 ************************************************************************/

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

/* 新线程调用的函数 */
void *thread_function(void *arg);

char message[] = "hello world";
int thread_finished = 0;

int main(){
	int res;
	pthread_t a_thread;

	/* 线程属性对象thread_attr */
	pthread_attr_t thread_attr;

	/* pthread_attr_init初始化一个线程属性对象 */
	res = pthread_attr_init(&thread_attr);
	if (res != 0) {
		perror("Attribute creation failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_attr_setdetachstate设置属性,PTHREAD_CREATE_DETACHED不允许调用pthread_join获得另一个线程的退出状态 */
	res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
	if (res != 0) {
		perror("Setting detached attribute failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_create创建一个新线程
	 * 第一个参数athread中存放新线程的标识符
	 * 第二个参数thread_attr为线程属性,上面的代码就是设置这个对象
	 * 第三个参数thread_function为新线程将要调用的函数 
	 * 第四个参数(void *)message为传递给将要调用函数的参数 */
	res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message);
	if (res != 0) {
		perror("Thread creation failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_attr_destroy函数对线程属性对象thread_attr进行清理和回收 */
	(void)pthread_attr_destroy(&thread_attr);
	/* 等待新线程函数设置thread_finished=1 */
	while (!thread_finished) {
		printf("Waiting for thread to say it's finished...\n");
		sleep(1);
	}
	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);
	printf("Second thread setting finished flag, and exiting now\n");
	thread_finished = 1;
	pthread_exit(NULL);
}
这个程序有两段比较重要的代码,第一段代码是:
pthread_attr_t thread_attr;
res = pthread_attr_init(&thread_attr);
它表明了一个线程属性并对其进行初始化,第二段代码是:
res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
它把属性的值设置为脱离状态.

2.线程属性--调度

该变调度属性和设置脱离状态非常相似,可以用sched_get_priority_max和sched_get_priority_min这两个函数来查找可用的优先级级别.
编写程序thread6.c
/*************************************************************************
 > File Name:    thread6.c
 > Description:  thread6.c程序设置线程的调度属性
 > Author:       Liubingbing
 > Created Time: 2015年07月06日 星期一 21时15分10秒
 > Other:        thread6.c程序先通过sched_get_priority获取允许的优先级范围,然后设置优先级为min_priority
 ************************************************************************/

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

/* 新线程调用的函数 */
void *thread_function(void *arg);

char message[] = "hello world";
int thread_finished = 0;

int main(){
	int res;
	pthread_t a_thread;
	int max_priority;
	int min_priority;
	struct sched_param scheduling_value;

	/* 线程属性对象thread_attr */
	pthread_attr_t thread_attr;

	/* pthread_attr_init初始化一个线程属性对象 */
	res = pthread_attr_init(&thread_attr);
	if (res != 0) {
		perror("Attribute creation failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_attr_setdetachstate设置属性,PTHREAD_CREATE_DETACHED不允许调用pthread_join获得另一个线程的退出状态 */
	res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
	if (res != 0) {
		perror("Setting detached attribute failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_attr_setschedpolicy设置调度策略*/
	res = pthread_attr_setschedpolicy(&thread_attr, SCHED_OTHER);
	if (res != 0) {
		perror("Setting scheduling policy failed");
		exit(EXIT_FAILURE);
	}
	/* 查找可用的优先级的范围 */
	max_priority = sched_get_priority_max(SCHED_OTHER);
	min_priority = sched_get_priority_min(SCHED_OTHER);
	/* 设置优先级 */
	scheduling_value.sched_priority = min_priority;
	res = pthread_attr_setschedparam(&thread_attr, &scheduling_value);
	if (res != 0) {
		perror("Seting scheduling priority failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_create创建一个新线程
	 * 第一个参数athread中存放新线程的标识符
	 * 第二个参数thread_attr为线程属性,上面的代码就是设置这个对象
	 * 第三个参数thread_function为新线程将要调用的函数 
	 * 第四个参数(void *)message为传递给将要调用函数的参数 */
	res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message);
	if (res != 0) {
		perror("Thread creation failed");
		exit(EXIT_FAILURE);
	}
	/* pthread_attr_destroy函数对线程属性对象thread_attr进行清理和回收 */
	(void)pthread_attr_destroy(&thread_attr);
	/* 等待新线程函数设置thread_finished=1 */
	while (!thread_finished) {
		printf("Waiting for thread to say it's finished...\n");
		sleep(1);
	}
	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);
	printf("Second thread setting finished flag, and exiting now\n");
	thread_finished = 1;
	pthread_exit(NULL);
}
这个程序与设置脱离状态属性很相似,区别只是设置的是调度策略.


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:102866次
    • 积分:3313
    • 等级:
    • 排名:第10257名
    • 原创:232篇
    • 转载:5篇
    • 译文:0篇
    • 评论:10条
    最新评论