GNU/Linux >> Tutoriels Linux >  >> Linux

Je veux attendre à la fois un descripteur de fichier et un mutex, quelle est la méthode recommandée pour le faire ?

Chaque fois que l'on utilise une architecture pilotée par les événements, il est nécessaire d'avoir un mécanisme unique pour signaler l'achèvement de l'événement. Sous Linux, si l'on utilise des fichiers, il est nécessaire d'utiliser quelque chose de la famille select ou poll, ce qui signifie que l'on est obligé d'utiliser un canal pour lancer tous les événements liés à aucun fichier.

Modifier :Linux a eventfd et timerfd. Ceux-ci peuvent être ajoutés à votre epoll list et utilisé pour sortir du epoll_wait lorsqu'il est déclenché à partir d'un autre thread ou lors d'un événement de minuterie, respectivement.

Il y a une autre option et c'est les signaux. On peut utiliser fcntl modifier le descripteur de fichier de sorte qu'un signal soit émis lorsque le descripteur de fichier devient actif. Le gestionnaire de signal peut ensuite pousser un message prêt à l'emploi sur n'importe quel type de file d'attente de votre choix. Il peut s'agir d'un simple sémaphore ou d'une file d'attente mutex/condvar. Puisque l'on n'utilise plus select /poll , il n'est plus nécessaire d'utiliser un tube pour mettre en file d'attente les messages non basés sur des fichiers.

Avertissement sanitaire :je n'ai pas essayé cela et bien que je ne vois pas pourquoi cela ne fonctionnera pas, je ne connais pas vraiment les implications en termes de performances du signal approche.

Edit :Manipuler un mutex dans un gestionnaire de signal est probablement une très mauvaise idée.


J'ai résolu ce problème exact en utilisant ce que vous mentionnez, pipe() et libevent (qui enveloppe epoll). Le thread de travail écrit un octet dans son tube FD lorsque sa file d'attente de sortie passe de vide à non vide. Cela réveille le thread IO principal, qui peut alors saisir la sortie du thread de travail. Cela fonctionne très bien et est en fait très simple à coder.


Vous avez la balise Linux, je vais donc jeter ceci :les files d'attente de messages POSIX font tout cela, ce qui devrait répondre à votre demande "intégrée", sinon à votre souhait multiplateforme moins souhaité.

La synchronisation thread-safe est intégrée. Vous pouvez bloquer vos threads de travail lors de la lecture de la file d'attente. Alternativement, les MQ peuvent utiliser mq_notify() pour créer un nouveau thread (ou en signaler un existant) lorsqu'un nouvel élément est placé dans la file d'attente. Et puisqu'il semble que vous allez utiliser select(), l'identifiant de MQ (mqd_t) peut être utilisé comme descripteur de fichier avec select.


Linux
  1. Qu'est-ce qu'un TAM et pourquoi voudriez-vous en être un ?

  2. Quelle est la différence entre le mutex et la section critique ?

  3. Quelle est la meilleure façon de s'assurer qu'une seule instance d'un script Bash est en cours d'exécution ?

  4. Quelle est la différence entre la section et le segment au format de fichier ELF

  5. Quel est le moyen le plus rapide de déplacer un million d'images d'un répertoire à un autre sous Linux ?

Comment ajouter des commandes Linux à la file d'attente et les exécuter une par une

Terraform vs Ansible :quelle est la différence et lequel utiliser ?

Quelles sont les différences entre `chattr +i FILE` et `chmod -w FILE` ?

Quelle est la différence entre fsync et syncfs ?

Qu'est-ce qui est le plus efficace - la compression tar ou zip ? Quelle est la différence entre tar et zip ?

Quelle est la commande pour copier, lire et supprimer un fichier sous Linux