2017-04-11 10 views
1

J'essaie de jouer avec la priorité avec POSIX. Mon but est d'avoir le programme suivant. Deux threads exécutent Thread0 avec une priorité de 10 et Thread1 avec la priorité de 50. Le thread Thread1 dans une boucle finie (comme 3 secondes) et dans cet intervalle de temps Thread0 essaye de s'exécuter lui-même. Le résultat devrait être le Thread0 sera bloqué parce qu'un thread avec une priorité plus élevée est en cours d'exécution.Priorité du fil avec posix

Mon résultat est que la priorité ne change pas le comportement du thread ... Je compile avec la commande suivante gcc -Wall -o ordonnancement scheduling3.c -pthread et avec la commande sudo su sur ubuntu. Résultat:

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 

Résultat que je veux:

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 

Programme:

// 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

Quel système d'exploitation? Dans mon expérience sur les systèmes d'exploitation non temps réel, la définition de choses comme la priorité de thread et/ou de processus a peu ou pas d'effet, et l'effet qu'ils ont est non-déterministe. Si vous avez besoin d'un processus pour s'exécuter plus souvent ou d'événements dans un certain ordre, vous devez utiliser explicitement les objets de synchronisation tels que les mutex, les variables de condition et les sémaphores et le coder vous-même. Si vous avez besoin d'une priorité et/ou d'une planification déterministe, vous devez utiliser les bons outils pour le travail, et un système d'exploitation généraliste n'est pas cet outil. –

Répondre

1

Cette boucle est appelée une "boucle occupée", il ne donne pas un planificateur du système d'exploitation façon de planifier d'autres threads. Vous devriez utiliser une variante de sleep().

0

« Le résultat devrait être le Thread0 sera bloqué car un thread avec une priorité plus élevée est en cours d'exécution »

Non, pas avec la quasi-totalité du matériel couramment disponible aujourd'hui.

Les threads ne resteront prêts, en attente d'exécution, que s'il y a plus de threads prêts/en cours d'exécution que de cœurs disponibles pour les exécuter. Avec deux threads, vous devriez remarquer quelque chose comme vous attendiez sur un processeur avec un seul noyau.

Ils sont très rares maintenant.