優先度反転問題のまとめ(二)


まず、プログラミングサンプルコードはシングルコア環境でテストされ、マルチコア環境ではcpuが負荷等化されます.サンプルコードは、リアルタイムカーネルと非リアルタイムカーネルの両方で正常に実行されました.
(1)ソースコードpthreadtest 1.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<time.h>
#include<sys/stat.h>
#include<fcntl.h>
#define __USE_GNU
#include<sched.h>
#include<ctype.h>
 /*        */
pthread_mutex_t mymutex;
pthread_mutexattr_t mattr;
void *thread_function_low(void *arg)
{
 printf("low thread in
");  pthread_mutex_lock(&mymutex);  int j=2500000000;  while(j--);  printf("low thread end!
");  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
",tid,middle_id);  int j=2500000000;  int i=100;  while(j--);  printf("middle thread end!
"); } 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
",tid,high_id);  pthread_mutex_lock(&mymutex);  int j=2500000000;    while(j--);  printf("high thread end!
");  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 
");  }  else  printf("protocol set error
");  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
");  }  param.sched_priority=70;  pthread_attr_setschedparam(&attr,&param);  printf("sched_priority:%u
",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,&param);  printf("sched_priority:%u
",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,&param);  printf("sched_priority:%u
",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:3つのスレッドを作成する
まず、スレッドのプロパティに関する設定を行います.
次に、設定したスレッドプロパティを使用して3つのスレッドを作成し、作成順序は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)スレッド属性について説明すべきいくつかの問題
    //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");}//スレッドの優先度paramを設定する.sched_priority=70; pthread_attr_setschedparam(&attr,¶m); printf("sched_priority:%u",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コンパイルオプションは、反発ロックプロトコルの設定をサポートするためです.
    コンパイルエラーの解決:
    http://bbs.csdn.net/topics/260054382
    テスト結果:
    a:マルチコアでは負荷が均衡し、テスト結果は以下の通りである.
     [root@fedora-t410 pthread]# ./pthtest1protocol set ok schedpolicy:SCHED_FIFOsched_priority:70//low thread prioritysched_priority:90//high thread prioritylow thread insched_priority:80//middle thread prioritythread_function_high -1224950976 in,pid is : 3056thread_function_midle -1233343680 in,pid is:3056low thread end!high thread end!middle thread end! 
    b:シングルコアでの優先順位継承プロトコルの実現:
     [root@fedora-t410 pthread]# ./pthtest1protocol set ok schedpolicy:SCHED_FIFOsched_priority:70//low thread prioritylow thread insched_priority:90//high thread prioritysched_priority:80//middle thread prioritythread_function_high -1224950976 in,pid is : 2352low thread end!high thread end!thread_function_midle -1233343680 in,pid is:2352middle thread end!