Mutexes du kernel Linux

Je lis “Pilotes de périphériques Linux 3ème édition”, le chapitre sur la concurrence et les conditions de course. Il y a un exemple que je ne comprends pas complètement; ils parlent d’un modèle commun dans la programmation du kernel, quand il faut lancer une activité (par exemple, nouveau thread ou processus utilisateur du kernel, demande de processus existant ou action basée sur le matériel) en dehors du thread en cours, attendre que cette activité se produise. Achevée. L’exemple de solution peu efficace est:

struct semaphore sem; init_MUTEX_LOCKED(&sem); start_external_task(&sem); down(&sem); 

Ensuite, ils suggèrent la tâche externe à appeler (& sem) lorsque son travail est terminé.

Je ne comprends pas pourquoi on ne peut pas le faire de cette façon:

 struct semaphore sem; down(&sem); start_external_task(&sem); 

Pourquoi est-il nécessaire de créer un mutex à l’état verrouillé, puis d’acquérir le mutex après le démarrage de la tâche?

J’attends de vos nouvelles! Merci.

Lorsque vous appelez (), votre thread se bloquera jusqu’à ce qu’un autre thread signale le sémaphore. Comme l’autre thread n’est pas encore démarré, le thread va se bloquer indéfiniment. C’est pourquoi vous devez d’abord démarrer le thread, puis appeler () pour bloquer jusqu’à la fin du thread.

Si le thread finit avant d’appeler (), ça va, car le sémaphore sera signalé et down () effacera simplement le signal et reviendra.

Dans le premier exemple, down (& sem) attendra que external_task appelle (& sem) et suspende efficacement le thread principal jusqu’à la fin de la tâche. Dans votre code down () va verrouiller le thread principal pour toujours car il n’y a pas encore de tâche à appeler ()

L’appel:

 init_MUTEX_LOCKED(&sem); 

Crée un nouveau sémaphore en “mode mutex” initialisé à 0. Cela signifie qu’un appel à down() sera bloqué. Un appel correspondant:

 init_MUTEX(&sem); 

Créerait un sémaphore initialisé à 1.

Dans le premier exemple, vous initialisez le sémaphore à 0, vous créez votre external_task et vous appelez down() blocage jusqu’à ce que votre tâche appelle up() .

Dans le second exemple, vous n’initialisez pas votre sémaphore, vous appelez down() bloquant l’exécution et vous n’avez aucun fichier external_task en cours d’exécution qui peut appeler up() pour vous débloquer. L’appel à créer external_task n’est donc jamais atteint.

Incidemment, le processus d’initialisation du sémaphore avec init_MUTEX_LOCKED a été supprimé dans la version 2.6.37 du kernel.