Question

Je travaille sur une application d'espace utilisateur pour un projet Linux intégré à l'aide du noyau 2.6.24.3. Mon application transmet les données entre deux nœuds de fichiers en créant 2 pthreads qui dorment chacun jusqu'à ce qu'une opération IO asynchrone se termine à quel point il se réveille et exécute un gestionnaire d'achèvement.

Les gestionnaires d'achèvement doivent garder une trace du nombre de transferts en attente et maintenir une poignée de listes liées auxquelles un thread ajoutera et l'autre supprimera.

// sleep here until events arrive or time out expires
for(;;) {
    no_of_events = io_getevents(ctx, 1, num_events, events, &timeout);
    // Process each aio event that has completed or thrown an error
    for (i=0; i<no_of_events; i++) {
        // Get pointer to completion handler
        io_complete = (io_callback_t) events[i].data;
        // Get pointer to data object
        iocb = (struct iocb *) events[i].obj;
        // Call completion handler and pass it the data object
        io_complete(ctx, iocb, events[i].res, events[i].res2);
    }
}

Ma question est ceci ...

Existe-t-il un moyen simple que je puisse empêcher le thread actuellement actif de céder pendant qu'il exécute le gestionnaire d'achèvement plutôt que de descendre la route Mutex / Spin Lock?

Ou à défaut qui peut être configuré pour éviter de donner un pthread lorsqu'un verrou de mutex / spin est maintenu?

Était-ce utile?

La solution

Vous pouvez utiliser le sched_setscheduler() Appel système pour définir temporairement la stratégie de planification du thread SCHED_FIFO, puis remettez-le à nouveau. Du sched_setscheduler() Page de l'homme:

UN SCHED_FIFO Le processus s'exécute jusqu'à ce qu'il soit bloqué par une demande d'E / S, il est préempté par un processus de priorité plus élevé, ou il appelle sched_yield(2).

(Dans ce contexte, le "processus" signifie réellement "thread").

Cependant, c'est une exigence tout à fait suspecte. Quel est le problème que vous espérez résoudre? Si vous essayez simplement de protéger votre liste liée des gestionnaires d'achèvement de l'accès simultané, alors un mutex ordinaire est la voie à suivre. Demandez au fil d'achèvement de verrouiller le mutex, supprimez l'élément de liste, déverrouillez le mutex, puis appelez le gestionnaire d'achèvement.

Autres conseils

Je pense que vous voudrez utiliser des mutex / verrous pour éviter les conditions de course ici. Les mutexes ne sont en aucun cas vaudou et peuvent même simplifier votre code que d'utiliser des fonctionnalités arbitraires spécifiques au système, dont vous auriez besoin de potentiellement de transférer entre les systèmes. Je ne sais pas si ce dernier est un problème pour vous, cependant.

Je crois que vous essayez de déjouer le planificateur Linux ici, pour de mauvaises raisons.

La bonne solution consiste à utiliser un mutex pour empêcher les gestionnaires d'achèvement de fonctionner en parallèle. Laissez le planificateur faire son travail.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top