C'est une vieille question, mais quand même.
Les threads POSIX sous Linux dans la glibc (NPTL) sont implémentés à l'aide de deux signaux en temps réel. Ils sont cachés à l'utilisateur (en ajustant les constantes de nombre min/max). Tous les événements où l'appel à la bibliothèque doit être propagé à tous les threads (comme setuid
) se font via ceux-ci :le thread appelant envoie un signal à tous les threads pour appliquer la modification, attend l'accusé de réception et continue.
E/S asynchrones.
Les signaux en temps réel sont le mécanisme permettant au noyau d'informer votre système lorsqu'une opération d'E/S est terminée.
struct aiocb
établit la connexion entre une requête d'E/S asynchrone et un numéro de signal.
Tout d'abord, notez que la réponse de Ben est correcte. Autant que je sache, le but des signaux en temps réel dans POSIX est de servir de mécanisme de livraison en temps réel pour AIO, les notifications de file d'attente de messages, les expirations de minuterie et les signaux définis par l'application (à la fois internes et inter-processus).
Cela dit, les signaux en général sont une très mauvaise façon de faire les choses :
- Les gestionnaires de signaux sont asynchrones, et à moins que vous vous assuriez qu'ils n'interrompent pas une fonction async-signal-unsafe, ils ne peuvent utiliser que des fonctions async-signal-safe, ce qui limite considérablement ce qu'ils peuvent faire.
- Les gestionnaires de signaux sont des états globaux. Une bibliothèque ne peut pas utiliser de signaux sans un contrat avec le programme appelant concernant les signaux qu'elle est autorisée à utiliser, s'il est autorisé à les rendre syscall-interrupting, etc. Et en général, l'état global est juste Une mauvaise chose .
- Si vous utilisez
sigwait
(ou Linuxsignalfd
extension) plutôt que des gestionnaires de signaux pour traiter les signaux, ils ne sont pas meilleurs que d'autres mécanismes IPC/notification, et encore potentiellement pires.
Les E/S asynchrones sont bien mieux réalisées en ignorant l'API POSIX AIO mal conçue et en créant simplement un thread pour effectuer des E/S de blocage normales et appeler pthread_cond_signal
ou sem_post
lorsque l'opération se termine. Ou, si vous pouvez vous permettre un peu de coût de performance, vous pouvez même vous transférer les données qui viennent d'être lues via un tube ou une paire de sockets, et faire en sorte que le thread principal traite les fichiers normaux lus de manière asynchrone avec select
ou poll
comme vous le feriez avec des sockets/pipes/ttys.