14 votes

Comment permettre à certains threads d'avoir la priorité pour verrouiller un mutex en utilisant PTHREADS

Supposons que le code suivant soit exécuté par 10 threads.

pthread_mutex_lock(&lock)
Some trivial code
pthread_mutex_unlock(&lock)

Pour les besoins de l'explication, disons que les fils sont T1, T2, T3.....T10. Mon exigence est que tant que T1 ou T2 ou T3 (c'est-à-dire n'importe lequel de T1, T2 ou T3) attende pour acquérir un verrou, les autres threads, c'est-à-dire T4, T5, T6.....T10, ne puissent pas acquérir le verrou, c'est-à-dire que T1, T2 et T3 aient la priorité pour acquérir le verrou par rapport aux autres threads.

Je suppose que cela peut être fait en augmentant la priorité des threads T1, T2 et T3.

Voici le pseudo-code

if this thread is T1 or T2 or T3
increase its priority 
pthread_mutex_lock(&lock)
Some trivial code
pthread_mutex_unlock(&lock)
if this thread is T1 or T2 or T3 decrease it priority to normal

Veuillez noter que je veux une solution qui fonctionne pour la plateforme Linux et qui doit utiliser pthreads. Je ne me soucie pas vraiment des autres plateformes.

Notez également que je ne veux pas vraiment que ces 3 threads soient en temps réel, je veux qu'ils aient leur comportement habituel (ordonnancement et priorité) sauf que dans le petit morceau de code mentionné ci-dessus, je veux qu'ils aient toujours la priorité pour acquérir un verrou.

J'ai lu quelques pages de manuel sur les politiques et les priorités d'ordonnancement sous Linux, mais je ne comprends pas vraiment :(

Est-ce que ça va marcher ? Pouvez-vous m'indiquer l'API pthread exacte requise pour accomplir la tâche ci-dessus ?

Salutations lali

0voto

Dummy00001 Points 6088

Pour implémenter cela avec pthreads, vous auriez besoin de N listes, une par priorité de thread. Les listes contiendraient des pointeurs vers les variables pthread_cond_t du thread.

Méta-code schématique non testé :

/* the main lock */
pthread_mutex_t TheLock = PTHREAD_MUTEX_INITIALIZER;

/* service structures: prio lists and the lock for them */
pthread_mutex_t prio_list_guard = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t *prio_lists[MY_MAX_PRIO][MY_MAX_THREAD]; /* 0 == highest prio */

/* lock */
void
prio_lock(int myprio)
{
    pthread_cond_t x;

    pthread_mutex_lock( &prio_list_guard );

    if (0 == pthread_mutex_trylock( &TheLock )) {
        pthread_mutex_unlock( &prio_list_guard );
        return 0;
    }

    pthread_cond_init( &x, 0 );
    LIST_ADD( prio_lists[myprio], &x )

    while(1)    /* handle spurious wake-ups */
    {
        pthread_cond_wait( &prio_list_guard, &x );
        if (0 == pthread_mutex_trylock( &TheLock )) 
        {
            LIST_REMOVE( prio_lists[myprio], &x );
            pthread_mutex_unlock( &prio_list_guard );
            return 0;
        }
    }
}

/* unlock */
void
prio_unlock()
{
    int i;
    pthread_cond_t *p;

    pthread_mutex_lock( &prio_list_guard );

    for (i=0; i<MY_MAX_PRIO; i++)
    {
        if ((p = LIST_GETFIRST( prio_lists[i] )))
        {
            pthread_cond_signal( p );
            break;
        }
    }

    pthread_mutex_unlock( &TheLock );

    pthread_mutex_unlock( &prio_list_guard );
}

Le code gère également les réveils intempestifs de pthread_cond_wait() mais franchement, je n'ai jamais vu cela arriver.

Edit1. Notez que prio_lists ci-dessus est une forme primitive d'un file d'attente prioritaire .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X