La planification des processus est une fonction importante du noyau dans les systèmes Linux. Elle peut allouer les droits d'utilisation du processeur entre plusieurs processus afin que chaque processus puisse obtenir une durée d'exécution raisonnable, améliorant ainsi la concurrence et la réactivité du système. L'effet de la planification des processus affecte directement les performances du système et l'expérience utilisateur. Il est donc essentiel de comprendre la planification des processus dans les systèmes Linux. Mais comprenez-vous vraiment la planification des processus dans les systèmes Linux ? Connaissez-vous ses concepts, principes et méthodes ? Savez-vous comment utiliser et configurer la planification des processus sous Linux ? Cet article vous présentera en détail les connaissances pertinentes sur la planification des processus dans les systèmes Linux, vous permettant de mieux utiliser et comprendre cette puissante fonction du noyau sous Linux.
Dans le noyau Linux, la complétion est un simple mécanisme de synchronisation qui signale que « les choses peuvent continuer ».
Pour utiliser la complétion, vous devez inclure
Cette variable peut être déclarée et initialisée statiquement :
DECLARE_COMPLETION(mon_comp);
ou initialisation dynamique :
1. **struct** completion my_comp; 2. init_completion(&my_comp);
Si le pilote souhaite attendre la fin d'un processus avant d'effectuer les opérations suivantes, il peut appeler wait_for_completion avec en paramètre l'événement à terminer :
wait_for_completion attend la fin. Si l'interruptible est ajouté, cela signifie que le thread en attente peut être interrompu par des signaux envoyés de l'extérieur ; si killable est ajouté, cela signifie que le thread ne peut être interrompu que par le signal kill, cela signifie que l'attente est terminée ; se terminera automatiquement après avoir attendu un certain temps. L'unité de délai d'attente est la tranche de temps utilisée par le système (généralement 1 ms).
Si d'autres parties du code peuvent déterminer que l'événement est terminé, l'une des deux fonctions suivantes peut être appelée pour réveiller le processus en attente de l'événement :
1. **void** complete(**struct** completion *comp); 2. **void** complete_all(**struct** completion *comp); /* Linux 2.5.x以上版本 */
La première fonction ne réveillera qu'un seul processus en attente, tandis que la seconde fonction réveillera tous les processus en attente de l'événement. En raison de la manière dont l'achèvement est implémenté, complete fonctionnera même s'il est appelé avant wait_for_competion.
Par exemple, dans l'implémentation du pilote de périphérique MD, il existe un thread de récupération md_recovery_thread. Le pilote enregistre et désenregistre les threads de récupération via md_register_thread et md_unregister_thread. La logique d'exécution de la restauration du thread se trouve dans la fonction md_thread, qui est à peu près la suivante :
1. **int** md_thread(**void** * arg) 2. { 3. 线程初始化; 4. **while** (运行) { 5. 处理逻辑; 6. 接收信号; 7. } 8. **return** 0; 9. }
md_register_thread créera un thread de récupération, qui doit renvoyer le pointeur du thread une fois le thread réellement initialisé. La logique est donc la suivante :
1. mdk_thread_t *md_register_thread(**void** (*run) (**void** *), **void** *data, **const** **char** *name) 2. { 3. mdk_thread_t ***thread**; 4. …… 5. **struct** completion event; 6. /* 为线程分配空间 */ 7. **thread** = (mdk_thread_t *) kmalloc (**sizeof**(mdk_thread_t), GFP_KERNEL); 8. …… 9. init_completion(&event); 10. …… 11. **thread**->event = &event; 12. /* 创建内核线程 */ 13. ret = kernel_thread(md_thread, **thread**, 0); 14. /* 等待线程初始化结束 */ 15. …… 16. wait_for_completion(&event); 17. /* 返回线程指针 */ 18. **return** **thread**; 19. }
Pendant que md_unregister_thread se déconnecte et reprend le thread en envoyant le signal SIGKILL au thread, il doit également libérer la mémoire occupée par le thread après la sortie réelle du thread. La logique est donc la suivante :
1. **void** md_unregister_thread(mdk_thread_t ***thread**) 2. { 3. **struct** completion event; 4. init_completion(&event); 5. **thread**->event = &event; 6. …… 7. /* 向线程发送SIGKILL信号终止其运行 */ 8. md_interrupt_thread(**thread**); 9. /* 等待线程退出 */ 10. wait_for_completion(&event); 11. /* 释放线程所占用的内存 */ 12. kfree(**thread**); 13. }
Si vous considérez l'achèvement, la logique de md_thread est :
1. **int** md_thread(**void** * arg) 2. { 3. 线程初始化; 4. complete(**thread**->event); 5. **while** (运行) { 6. 处理逻辑; 7. 接收信号; 8. } 9. complete(**thread**->event); 10. **return** 0; 11. }
Il convient de noter que puisque l'événement d'attente est une ressource partagée dans le pilote et le thread de récupération, il doit s'agir d'une variable globale, ou comme dans le code d'implémentation, définie comme une variable locale, et son pointeur est placé dans le thread de récupération milieu de structure.
typedef struct mdk_thread_s { …… struct completion *event; …… } mdk_thread_t;
Grâce à cet article, vous devez avoir une compréhension approfondie de la planification des processus dans les systèmes Linux et connaître ses concepts, principes et méthodes. Vous devez également comprendre le rôle et l'impact de la planification des processus, ainsi que comment utiliser et configurer correctement la planification des processus sous Linux. Nous vous recommandons d'utiliser la planification des processus pour améliorer la simultanéité et la réactivité du système lorsque vous utilisez un système Linux. Dans le même temps, nous vous rappelons également de prêter attention à certains problèmes et défis potentiels lors de l'utilisation de la planification des processus, tels que la priorité des processus, l'équilibrage de charge, les performances en temps réel, etc. J'espère que cet article pourra vous aider à mieux utiliser le système Linux et vous permettre de profiter des avantages et de la commodité de la planification des processus sous Linux.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!