2017-04-11 7 views
1

私はPOSIXの優先順位でプレイしようとしています。私の目標は、次のプログラムを持つことです。 2つのスレッドは、優先度10のThread0と優先度50のThread1を実行しています。有限ループ(3秒など)のThread1ブロックと、この時間間隔Thread0は自分自身を実行しようとします。その結果、より高い優先度を持つスレッドが実行されているため、Thread0がブロックされるはずです。POSIXでのスレッドの優先度

私の結果は、スレッドの振る舞いを変えないということです。次のコマンドgcc -Wall -oを使ってコンパイルします。スケジューリング3c -pthread とubuntuのsudo suコマンドでコンパイルします。 結果:

Prio min = 1, Prio max = 99 
SCHED_FIFO 
Priority of the thread 0 : 10 
SCHED_FIFO 
Priority of the thread 1 : 50 
Value of test_thread_0 1 
Value of test_thread_1 1 

私が欲しい結果:

Prio min = 1, Prio max = 99 
SCHED_FIFO 
Priority of the thread 0 : 10 
SCHED_FIFO 
Priority of the thread 1 : 50 
Value of test_thread_0 1 
Value of test_thread_1 1 

はプログラム:

// The thread with high priority wil block the thread with low priority 
// Run with super user privilege (sudo su with ubuntu) 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/time.h> 
#include <time.h> 
#include <pthread.h> 
#include <errno.h> 

#define NUM_THREADS  2 

int test_thread_0 = 0; 
int test_thread_1 = 0; 



void *BlockThread0(void *threadid) { 
    test_thread_0 = 1;  
} 

void *BlockThread1(void *threadid) { 
    struct timeval start, end; 
    long secs_used; 
    gettimeofday(&start, NULL); 
    test_thread_1 = 1; 

    while(1) { 
     gettimeofday(&end, NULL); 
     secs_used=(end.tv_sec - start.tv_sec); //avoid overflow by subtracting first 
     if(secs_used > 3) 
      break; 
    } 

} 


int main(int argc, char *argv[]) { 
    int i, policy; 
    pthread_t tid[NUM_THREADS]; 
    pthread_attr_t attr[NUM_THREADS]; 
    struct sched_param param[NUM_THREADS], test; 
    int prio_max, prio_min; 

    // Get the range of the policy 
    prio_max = sched_get_priority_max(SCHED_FIFO); 
    prio_min = sched_get_priority_min(SCHED_FIFO); 
    printf("Prio min = %d, Prio max = %d \n", prio_min, prio_max); 

    // Set the different priority 
    param[0].sched_priority = 10; 
    param[1].sched_priority = 50; 

    // Set all the attribute (policy + priority) 
    for(i = 0; i < NUM_THREADS; i++) { 

     pthread_attr_init(&attr[i]); 

     if(pthread_attr_setinheritsched(&attr[i], PTHREAD_EXPLICIT_SCHED) != 0) 
      fprintf(stderr, "Unable to set EXPLICIT SCHEDULER.\n"); 

     pthread_attr_setdetachstate(&attr[i], PTHREAD_CREATE_JOINABLE); 

     /* The attribute get the new policy */ 
     if(pthread_attr_setschedpolicy(&attr[i], SCHED_FIFO) != 0) 
      fprintf(stderr, "Unable to set policy.\n"); 

     /* Test to change the priority of each task */ 
     if(pthread_attr_setschedparam(&attr[i], &param[i]) != 0) 
      fprintf(stderr, "Unable to set priority.\n"); 
    } 

    // Get all the attribute (policy + priority) 
    for(i = 0; i < NUM_THREADS; i++) { 
     // Get the policy 
     if(pthread_attr_getschedpolicy(&attr[i], &policy) != 0) 
      fprintf(stderr, "Unable to get policy.\n"); 
     else{ 
      if(policy == SCHED_OTHER) 
       printf("SCHED_OTHER\n"); 
      else if(policy == SCHED_RR) 
       printf("SCHED_RR\n"); 
      else if(policy == SCHED_FIFO) 
       printf("SCHED_FIFO\n"); 
     } 
     /* Get the priority */ 
     pthread_attr_getschedparam(&attr[i], &test); 
     printf("Priority of the thread %d : %d \n",i,test.sched_priority); 
    } 

    // Thread1 with the most important priority is executing 
    pthread_create(&tid[1], &attr[1], BlockThread1, (void *)1); 

    // To be sure that the thread1 is running 
    sleep(1); 


    //Thread2 with lower priority attempt to execute himself but he is blocked because thread1 is executing 
    pthread_create(&tid[0], &attr[0], BlockThread0, (void *)0); 

    /* now join on each thread */ 
    for(i = 0; i < NUM_THREADS; i++) 
     pthread_join(tid[i], NULL); 

    printf("Value of test_thread_0 %d \n",test_thread_0); 
    printf("Value of test_thread_1 %d \n",test_thread_1); 

} 
+2

どのようなOSですか?非リアルタイムオペレーティングシステムでの私の経験では、スレッドやプロセスの優先度などの設定はほとんど効果がありませんし、それらの影響は非決定的です。特定の順序で実行するプロセスを頻繁に実行する必要がある場合は、mutex、条件変数、セマフォなどの同期オブジェクトを明示的に使用し、自分でコーディングする必要があります。確定的な優先順位やスケジューリングが必要な場合は、ジョブに適切なツールを使用する必要があり、汎用OSはそのツールではありません。 –

答えて

1

ループは "忙しいループ" と呼ばれていること、それはOSのスケジューラaを与えるものではありません他のスレッドをスケジュールする方法。 sleep()の亜種を使用する必要があります。

0

今日一般的に入手可能なほぼすべてのハードウェアと

番号を未「優先度の高いスレッドが実行されているため、結果はThread0がブロックされるべきです」。

スレッドは、実行可能なコアよりも実行可能/実行中のスレッドが多い場合にのみ、実行を待機します。

2つのスレッドを使用すると、コアが1つしかないプロセッサで予期していたようなことに気付くはずです。

これは非常にまれです。

関連する問題