首页 > 代码库 > 第10章 线程控制(2)_线程属性和线程优先级
第10章 线程控制(2)_线程属性和线程优先级
3. 线程属性
3.1 线程属性结构体
(1)pthread_attr_t结构体
(2)线程属性初始化和销毁
头文件 |
#include <pthread.h> |
函数 |
int pthread_attr _init(pthread_attr_t* attr); //初始化 int pthread_attr_destroy(pthread_attr_t* attr); //销毁 |
返回值 |
成功返回0,否则返回错误编号 |
3.2 设置和获取分离属性
头文件 |
#include <pthread.h> |
函数 |
int pthread_attr _getdetachstat (const pthread_attr_t* attr, int* detachstate); //获取分离属性 int pthread_attr_setdetachstat (const pthread_attr_t* attr, int detachstate); //设置分离属性 |
返回值 |
成功返回0,否则返回错误编号 |
参数 |
detachstate的取值: ①PTHREAD_CREATE_JOINABLE(默认值) //正常启动线程 ②PTHREAD_CREATE_DETACHED //以分离状态启动线程 |
备注 |
(1)以默认方式启动的线程,在线程结束后不会自动释放占用的系统资源,要在主控线程中调用pthread_join()后才会释放。 (2)以分离状态启动的线程,在线程结束后会自动释放所占有的系统资源。 (3)分离属性在网络通讯中使用的较多。 |
【编程实验】线程分离属性
//pthread_detach.c
#include <pthread.h> #include <stdio.h> #include <stdlib.h> //线程函数 void* th_fn(void* arg) { int i = 0; int sum = 0; for(i=1; i<=100; i++){ sum += i; } return (void*)sum; } //输出线程属性 void out_state(pthread_attr_t* attr) { int state = 0; //获取分离属性 if(pthread_attr_getdetachstate(attr, &state)!=0){ perror("getdetachstate error"); }else{ if(state == PTHREAD_CREATE_JOINABLE){ printf("joinable state\n");//正常状态启动 }else if(state == PTHREAD_CREATE_DETACHED){ printf("detached state\n");//分离状态启动 }else{ printf("error state\n"); } } } int main(void) { int err; pthread_t default_th, detach_th; //定义线程属性 pthread_attr_t attr; //对线程属性初始化 pthread_attr_init(&attr); //输出分离属性:默认值 out_state(&attr); //方式1:以分离属性的默认值方式启动子线程(正常启动) if((err = pthread_create(&default_th, &attr, th_fn, (void*)0)) != 0){ perror("pthread create error"); } int res = 0; if((err = pthread_join(default_th, (void*)&res)) != 0){ perror("pthread join error"); }else{ printf("default return is %d\n", (int)res); } printf("----------------------------------------\n"); //方式2:设置线程属性为分离状态启动 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); out_state(&attr); //以分离状态启动子线程 if((err = pthread_create(&detach_th, &attr, th_fn, (void*)0))!=0){ perror("pthread create error"); } //注意:分离状态的子线程,调用pthread_join将失败! if((err = pthread_join(detach_th, (void*)&res)) != 0){ //perror("pthread join error"); fprintf(stderr, "%s\n", strerror(err)); }else{ printf("detach return is %d\n", (int)res); } //销毁线程属性 pthread_attr_destroy(&attr); printf("0x%lx finished\n", pthread_self()); sleep(1); return 0; } /*输出结果 joinable state //正常状态启动 default return is 5050 ---------------------------------------- detached state //分离状态启动 Invalid argument //调用pthread_join失败! 0xb77976bf finished */
3.3 线程优先级设置
(1)调度策略和获取最高/最低优先级
头文件 |
#include <pthread.h> #include <sched.h> |
函数 |
//设置调度策略 int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy); //获取可设置的最高、最低优先级 int sched_get_priority_max(int policy); int sched_get_priority_min(int policy); |
返回值 |
成功返回0,否则返回错误编号 |
参数 |
policy的取值 ①SCHED_OTHER:分时调度策略,不支持优先级使用。(默认调度策略) ②SCHED_FIFO:实时调度策略。一旦占用CPU则一直运行。直到有更高优先级到达或自己放弃 ③SCHED_RR:实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。 |
(2)获取和设置优先级
头文件 |
#include <pthread.h> #include <sched.h> |
函数 |
int pthread_attr_setschedparam(pthread_addr_t* attr, const struct sched_param* param); //设置优先级 int pthread_attr_getschedparam(const pthread_attr_t* attr, struct sched_param* param); //获取优先级 |
返回值 |
成功返回0,否则返回错误编号 |
参数 |
struct sched_param { int32_t sched_priority; //所要设定的线程优先级(1-99),数值越大,优先级越高。 }; |
【编程实验】设置线程优先级
//pthread_priority.c
#include <pthread.h> #include <sched.h> #include <stdio.h> #include <stdlib.h> /*改变线程调度策略和优先级*/ //显示线程的调度策略和优先级 void show_attr(int threadid, int policy, int priority) { printf("thread%d ", threadid); switch(policy) { case SCHED_OTHER: printf("policy = SCHED_OTHER"); break; case SCHED_RR: printf("policy = SCHED_RR"); break; case SCHED_FIFO: printf("policy = SCHED_FIFO"); break; default: printf("policy = UNKNOW"); break; } printf(" priority = %d\n", priority); } void* th_fn(void* arg) { int id = (int)arg; int i, j; int policy; struct sched_param param; //获取当前线程的线程调度策略和优先级 pthread_getschedparam(pthread_self(), &policy, ¶m); show_attr(id, policy, param.sched_priority); for(i=1; i<10;i++){ for(j=1;j<100000000;j++); printf("%d thread%d\n", i, id); } printf("thread%d exit\n", id); return (void*)0; } int main(void) { pthread_t t1, t2, t3; struct sched_param param; pthread_attr_t attr1, attr2, attr3; pthread_attr_init(&attr1); pthread_attr_init(&attr2); pthread_attr_init(&attr3); //线程1按默认的调度策略和优先级:SCHED_OTHER //线程2的调度策略为SCHED_RR,优先级为21 param.sched_priority = 21; pthread_attr_setschedpolicy(&attr2, SCHED_RR);//调度策略 pthread_attr_setschedparam(&attr2, ¶m); //优先级 pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED); //不继承父线程的调度策略, //而是由用户自己指定调度策略 //线程3的为SCHED_RR调度,优先级为51 param.sched_priority = 51; //数值越大,优先级越高! pthread_attr_setschedpolicy(&attr3, SCHED_RR); pthread_attr_setschedparam(&attr3, ¶m); pthread_attr_setinheritsched(&attr3, PTHREAD_EXPLICIT_SCHED); //创建3个子线程 pthread_create(&t1, &attr1, th_fn, (void*)1); pthread_create(&t2, &attr2, th_fn, (void*)2); pthread_create(&t3, &attr3, th_fn, (void*)3); //等待子线程结束 pthread_join(t1, NULL); pthread_join(t2, NULL); pthread_join(t3, NULL); //销毁线程属性 pthread_attr_destroy(&attr1); pthread_attr_destroy(&attr2); pthread_attr_destroy(&attr3); return 0; } /* 输出结果 * thread2 policy = SCHED_RR priority = 11 * 1 thread2 * 2 thread2 * 3 thread2 * thread1 policy = SCHED_OTHER priority = 0 * thread3 policy = SCHED_RR priority = 51 //线程1被线程3抢占 * 1 thread3 * 2 thread3 * 3 thread3 * 4 thread3 * 5 thread3 * 6 thread3 * 7 thread3 * 8 thread3 * 9 thread3 * thread3 exit * 4 thread2 * 5 thread2 * 6 thread2 * 7 thread2 * 8 thread2 * 9 thread2 * thread2 exit * 1 thread1 * 2 thread1 * 3 thread1 * 4 thread1 * 5 thread1 * 6 thread1 * 7 thread1 * 8 thread1 * 9 thread1 * thread1 exit *从输出结果看,得到如下结论: *(1)线程1为普通调度策略(SCHED_OTHER),线程2和线程3为时间片轮转实时调度策略(SCHED_RR) *(2)优先级高的线程3并没有最先运行,但获的时间片更多。 *(3)线程2、3为实时线程,所以最先运行完,线程1为普通线程最后运行结束。 */
第10章 线程控制(2)_线程属性和线程优先级