2010-04-29 8 views
3

Je me demandais simplement si en C est-il possible de jeter un coup d'oeil dans le tampon d'entrée ou d'effectuer une ruse similaire pour savoir si un appel à fgets bloquerait plus tard. Java permet de faire quelque chose comme ça en appelant BufferedReader.ready(), de cette façon que je peux mettre en œuvre quelque chose d'entrée de la console comme ceci:vérifier si fgets bloquerait

while (on && in.ready()) { 
    line = in.readLine(); 
    /* do something with line */ 
    if (!in.ready()) 
    Thread.sleep(100); 
} 

cela permet un filet extérieur de grâce shutdown la boucle d'entrée en mettant à faux ; Je voudrais effectuer une implémentation similaire en C sans avoir recours à des astuces non portables, je sais déjà que je peux faire un "time out" sous unix en recourant à des signaux ou (mieux, même si besoin de prendre soin de tamponner) réimplement au dessus de recv/select, mais je préférerais quelque chose qui fonctionnerait aussi sur windows.

TIA

+0

Select fonctionne sur Windows aussi: http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx – nc3b

+3

@ NC3B: La fonction select' de Windows 'fonctionne uniquement avec les sockets . –

+1

@Marcelo Cantos: Oh, désolé ne savait pas: "> – nc3b

Répondre

1

Suggérer aller avec prise I/routines O, poll() de préférence avec milliseconde requis comme délai et, éventuellement, vous pouvez interpréter timeout (valeur de retour = -1) la non-disponibilité des données dans un tampon d'entrée. À mon avis, il n'y a pas de fonction d'E/S standard non bloquante pour réaliser cette fonctionnalité.

0

Je ne sais pas de quoi vous parlez: un socket ou une poignée de fichier?

Pour les fichiers, il ne devrait pas y avoir de blocage. La fonction renvoie immédiatement (en plus de l'appel d'E/S lui-même).

Pour les sockets - vous pouvez utiliser la fonction ioctlsocket: Ce qui suit indique s'il y a une donnée RCV en attente:

ULONG nSize; 
ioctlsocket(sock, FIONREAD, &nSize); 

Les transferts suivant la socket en mode non-bloquant:

ULONG nEnable = 1; 
ioctlsocket(sock, FIONBIO, &nEnable); 

En mode non bloquant - les fonctions sur le socket ne bloquent jamais. S'ils ne peuvent pas répondre à la demande, ils renvoient une erreur et le code d'erreur est WSAEWOULDBLOCK

De plus, sous Windows, il existe des dizaines de méthodes beaucoup plus efficaces. Ce sont:

  • Utilisation d'E/S superposées. Ceci est non trivial, mais donne des performances supérieures
  • Associer socket avec un événement attendable. Cela transfère le socket à un mode non bloquant, plus l'événement spécifié est signalé lorsqu'un événement réseau se produit.
  • Associez-le à la poignée de la fenêtre. Ceci est pratique pour les programmes orientés UI.