首先说明一下:编程示例代码是在单核环境下测试,多核环境下cpu会进行负载均衡;示例代码在实时内核和非实时内核下均运行成功。
(1) 源代码pthreadtest1.c#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define __USE_GNU
#include
#include
/*设置互斥锁的协议*/
pthread_mutex_t mymutex;
pthread_mutexattr_t mattr;
void *thread_function_low(void *arg)
{
printf("low thread in\n");
pthread_mutex_lock(&mymutex);
int j=2500000000;
while(j--);
printf("low thread end!\n");
pthread_mutex_unlock(&mymutex);
}
void *thread_function_middle(void *arg)
{
pid_t middle_id;
middle_id=getpid();
pthread_t tid;//线程id
tid=pthread_self();//获取线程id*/
printf("thread_function_midle %d in,pid is:%d\n",tid,middle_id);
int j=2500000000;
int i=100;
while(j--);
printf("middle thread end!\n");
}
void *thread_function_high(void *arg)
{
pid_t high_id;
high_id=getpid();
pthread_t tid;//线程id
tid=pthread_self();//获取线程id*/
printf("thread_function_high %d in,pid is : %d\n",tid,high_id);
pthread_mutex_lock(&mymutex);
int j=2500000000;
while(j--);
printf("high thread end!\n");
pthread_mutex_unlock(&mymutex);
}
int main()
{
/*设置互斥锁属性*/
pthread_mutexattr_setpshared(&mattr,PTHREAD_PROCESS_PRIVATE);
int protocol;
int ret;
pthread_mutexattr_setprotocol(&mattr,PTHREAD_PRIO_INHERIT);//设置互斥锁协议
ret=pthread_mutex_init(&mymutex,&mattr);//调用此函数时,pshared属性的缺省值为PTHREAD_PROCESS_PRIVATE.该值表示可以在进程内使用经过初始化的互斥锁。
pthread_mutexattr_getprotocol(&mattr,&protocol);
if (protocol==PTHREAD_PRIO_INHERIT)
{
printf("protocol set ok \n");
}
else
printf("protocol set error\n");
pthread_t low_thread,middle_thread,high_thread;
int policy;
int max_priority,min_priority;
struct sched_param param;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
pthread_attr_getinheritsched(&attr,&policy);
pthread_attr_setschedpolicy(&attr,SCHED_FIFO);
pthread_attr_getschedpolicy(&attr,&policy);
if(policy==SCHED_FIFO)
{
printf("schedpolicy:SCHED_FIFO\n");
}
param.sched_priority=70;
pthread_attr_setschedparam(&attr,¶m);
printf("sched_priority:%u\n",param.sched_priority);
// pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&low_thread,&attr,thread_function_low,NULL);
/*创建第二个线程*/
param.sched_priority=90;
pthread_attr_setschedparam(&attr,¶m);
printf("sched_priority:%u\n",param.sched_priority);
//pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&high_thread,&attr,thread_function_high,NULL);
/*创建第三个线程*/
param.sched_priority=80;
pthread_attr_setschedparam(&attr,¶m);
printf("sched_priority:%u\n",param.sched_priority);
//pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&middle_thread,&attr,thread_function_middle,NULL);
pthread_join(low_thread,NULL);
pthread_join(middle_thread,NULL);
pthread_join(high_thread,NULL);
return 0;
}
整个程序的设计思路:
a: 定义互斥锁以及互斥锁的属性:
pthread_mutex_t : mymutex;
pthread_mutexattr_t mattr;
b:设置互斥锁的属性
设置锁的共享类型:pthread_mutexattr_setpshared(&mattr,PTHREAD_PROCESS_PRIVATE);//表示只在同一进程的不同线程之间共享锁。
设置锁的协议:pthread_mutexattr_setprotocol(&mattr,PTHREAD_PRIO_INHERINT);
用设置好的属性对锁进行初始化:pthread_mutex_init(&mymutex,&mattr);
c:创建三个线程
首先对线程的属性进行相关的设置;
然后使用设置好的线程属性创建三个线程,创建顺序分别为low thread,middle thread,high thread。
(2)使用互斥锁pthread_mutex_lock/pthread_mutex_unlock 对low thread和high thread进行互斥操作,关于互斥锁需要说明的几个问题:
a:是否使用优先级继承协议的互斥锁是需要对锁使用的协议进行设置的
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
函数作用:设置互斥锁使用的协议。
attr:互斥锁的属性;
protocol:互斥锁使用的协议;
返回值:成功返回0.不成功返回相应错误码。
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol);
函数作用:获取互斥锁使用的协议。
attr:互斥锁的属性;
protocol:互斥锁使用的协议;
返回值:成功返回0.不成功返回相应错误码。
其中协议包括以下几种:PTHREAD_PRIO_NONE:线程的优先级和调度不会受到互斥锁拥有权的影响。
PTHREAD_PRIO_INHERIT:当高优先级的等待低优先级的线程锁定互斥量时,低优先级的线程以高优先级线程的优先级运行。这种方式将以继承的形式传递。当线程解锁互斥量时,线程的优先级自动被将到它原来的优先级。(“优先级继承”意味着,当一个线程在由另一个低优先级线程拥有的互斥量上等待时,后者的优先级将被增加到等待线程的优先级.)该协议就是支持优先级继承类型的互斥锁,它不是默认选项,需要在程序中进行设置。
PTHREAD_PRIO_PROTECT:拥有该类型的互斥量的线程将以自己的优先级和它拥有的互斥量的线程将以自己的优先级和它拥有的互斥量的优先级较高者运行,其他等待该线程拥有的锁得线程对该线程的调度优先级没有影响。
(3)关于线程属性需要说明的几点问题
//创建三个线程
pthread_t low_thread,middle_thread,high_thread;
int policy;
int max_priority,min_priority;
//线程参数设置
struct sched_param param;
//线程属性
pthread_attr_t attr;
//使用默认值对线程属性进行初始化
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);//这个参数表示对该线程使用设置的属性
pthread_attr_getinheritsched(&attr,&policy);
//设置线程调度策略
pthread_attr_setschedpolicy(&attr,SCHED_FIFO);
pthread_attr_getschedpolicy(&attr,&policy);
if(policy==SCHED_FIFO)
{
printf("schedpolicy:SCHED_FIFO\n");
}
//设置线程的优先级
param.sched_priority=70;
pthread_attr_setschedparam(&attr,¶m);
printf("sched_priority:%u\n",param.sched_priority);
使用设置好的属性创建线程
pthread_create(&low_thread,&attr,thread_function_low,NULL);
编译命令:
#gcc -lpthread -lrt -std=c99 -D_SOURCE pthteadtest1.c -o pthtest1
-D_SOURCE 编译选项就是为了支持对互斥锁协议的设置。
解决编译出错问题:
测试结果:
a:多核下会负载均衡,测试结果如下:[root@fedora-t410 pthread]# ./pthtest1
protocol set ok
schedpolicy:SCHED_FIFO
sched_priority:70//low thread priority
sched_priority:90//high thread priority
low thread in
sched_priority:80//middle thread priority
thread_function_high -1224950976 in,pid is : 3056
thread_function_midle -1233343680 in,pid is:3056
low thread end!
high thread end!
middle thread end!
b:单核下的优先级继承协议的实现:[root@fedora-t410 pthread]# ./pthtest1
protocol set ok
schedpolicy:SCHED_FIFO
sched_priority:70//low thread priority
low thread in
sched_priority:90//high thread priority
sched_priority:80//middle thread priority
thread_function_high -1224950976 in,pid is : 2352
low thread end!
high thread end!
thread_function_midle -1233343680 in,pid is:2352
middle thread end!