线程属性的设置,网上找的文章总感觉不够全面,还是结合man手册查看。
线程属性设置,分两个方式,一种是在创建之前,通过pthread_attr_t
结构体传入,另一种,是线程创建完已经在运行时,通过部分函数设置。一般常见的是创建线程时传NULL,使用默认属性,后续运行时根据需要动态修改,也就第二种方式。
一:线程创建前设置属性:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
1.0 第一个参数,用来保存创建好后线程uid
2.0 第二个参数,即线程属性,通常传NULL,表示默认属性,这个属性在创建前可以设置,包括调度策略,栈大小,优先级等等
3.0 第三个参数,即线程入口函数
4.0 第四个参数,传给线程的参数
所以在创建线程前,对 第二个参数 pthred_attr_t 结构体进pthread_attr_t 进行赋值
1.0 pthread_attr_init(pthread_attr_t *attr);//使用默认值填充初始化
2.0//获取设置栈大小 //这个属性只能在线程创建前设置,后面不能动态修改了
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
3.0 //设置获取调度策略
SCHED_FIFO, SCHED_RR, and
SCHED_OTHER //policy支持这三种值,
1.0SCHED_OTHER 分时调度策略,
2.0SCHED_FIFO实时调度策略,先到先服务
3.0,SCHED_RR实时调度策略,时间片轮转
SCHED_OTHER(分时调度)是不支持优先级使用的,其他两个实时调度可以
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
4.0 //设置调度参数,目前这个参数里面就一个量,优先级 //用户程序设置实时任务这个优先级,值越大,优先级越高
(内核里面优先级是用另外的一个值,具体查看这个文章:
http://www.360doc.com/content/13/0801/09/7775902_303961368.shtml
<http://www.360doc.com/content/13/0801/09/7775902_303961368.shtml>)
struct sched_param {
int sched_priority; /* Scheduling priority */
};
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param
*param);
int pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param);
5.0//是否分离属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
上面这些都是静态,在创建线程之前的设置。
二:一般,都在线程创建完后,动态地设置:
1.0 设置调度策略和优先级
#include <sched.h>
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
int sched_getscheduler(pid_t pid); //获取线程当前优先级
struct sched_param {
int sched_priority;
};
//获取支持的最大最小值
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
2.0 设置分离属性
int pthread_detach(pthread_t thread);
int pthread_join(pthread_t thread, void **retval);
3.0 设置线程名称
调用 prctl(PR_SET_NAME, “my_threadname”);
线程默认名称,貌似是父进程的名称,未去考究,在linux上我们用 ps -p pid -T 来查看进程号为
pid的子线程的情况,如果用上面的方式设置了线程名称,则会列出名称
关于 prctl
process control, #man prctl 上面的是 (2),说明这是一个系统调用函数,根据他的全名顾名思义就是用来控制
process的,(linux内核里面的实现,线程其实就是进程,只是对进行了一些资源的共享,所以经常说线程是轻量级的进程)
关于ps 命令, -p 表示进程号,
-T表示列出子线程。所以上面设置线程名称,更多的时用来调试多线程程序的时候方便调试的,毕竟在程序里面直接用线程pid就可以唯一确定线程的身份了,但是没有名称看的直接,比如没有设置名称的线程:
看一下man手册里面详细的关于PR_SET_NAME的介绍
名称长度不能超过 16bytes(包含 结束符号'\0'),也可以通过库函数 pthread_setname_np来调用,线程的这个属性,可以通过
/proc文件系统来查看,即/proc/self/task/[tid]/comm
热门工具 换一换