2009-02-24 9 views
17

Si j'ai un programme qui crée et tente d'ouvrir un tube nommé en utilisant mkfifo, comment puis-je ouvrir un tube pour lire ou écrire sans bloquer? En particulier, j'écris un programme C qui peut être exécuté avec ou sans gui (écrit en Java).Comment effectuer une fopen non bloquante sur un tube nommé (mkfifo)?

Dans le programme C, je crée avec succès les tuyaux nommés avec mkfifo, mais quand je fais

FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/ 

fopen ne retourne pas jusqu'à ce que l'interface utilisateur graphique ouvre ce tuyau pour l'écriture. Ce que je souhaite faire est d'avoir ce tuyau prêt à être lu une fois (si) l'interface graphique décide d'y écrire - je mettrai le descripteur de fichier dans un appel select(). Il est raisonnable de s'attendre à ce que l'interface graphique Java ne soit jamais réellement démarrée, donc je ne peux pas compter sur elle pour ouvrir l'autre extrémité du tuyau à un point spécifique ou même du tout.

Je vais aussi avoir un deuxième tuyau ouvert pour l'écriture, et je suppose que je vais avoir le même problème. En outre, je ne peux pas définir O_NONBLOCK sur un tube de sortie qui n'a pas de lecteur.

Des suggestions?

(Ceci est en cours d'exécution sur un système Linux)

+0

Avez-vous besoin d'ouvrir le tuyau de sortie avant de sélectionner() le tir sur le tuyau d'entrée? –

+0

@tinkertim - Je suppose que techniquement non - je les ai tous les deux mis en place dans une fonction de configuration, mais je pourrais simplement configurer le tube de sortie d'abord, puis appeler select, pourquoi? – Zxaos

Répondre

12

Vous pouvez open() votre pipe O_RDONLY | O_NONBLOCK, et si vous voulez que le flux C, vous pouvez l'obtenir avec fdopen(). Cependant, il peut y avoir un problème avec le select() - AFAIK, un tube fd ouvert pour la lecture qui n'a aucun écrivain est toujours prêt à lire, et read() renvoie 0, de sorte que le select() se déclencherait indéfiniment. Une manière kludgy de surmonter ce serait d'ouvrir le tuyau O_RDWR; c'est-à-dire, avoir au moins un écrivain (votre programme C++). Ce qui résoudrait votre problème de toute façon.

+1

Je vais donner une chance pour le lecteur - mais je ne peux pas mettre O_NONBLOCK sur un tuyau de sortie ... – Zxaos

+1

La norme POSIX dit (de select()): "Un descripteur doit être considéré comme prêt pour la lecture quand un appel à une fonction d'entrée avec O_NONBLOCK clear ne bloquerait pas, que la fonction transfère ou non des données avec succès. " (POSIX.1: 2008). –

+1

L'ouverture du tube O_RDWR conduirait à un interblocage lorsque le programme lit (ou écrit) - à moins qu'il n'y ait en fait un autre processus avec le tuyau ouvert. –

Questions connexes