2010-06-11 11 views
8

Ich verwende Linux als meine Programmierplattform. Ich verwende poll(2), um zu wissen, ob mein Gerät ein Ereignis auslöst. Der erste Anruf von poll ist in Ordnung; Es blockiert und wartet auf das Ereignis. Aber in der zweiten poll Funktionsaufruf wird es zurückkehren; aber es fängt das Ereignis ein. Unten ist mein Code.Poll (2) löscht die Ereigniswarteschlange nicht

ret = poll(fds, 1, 2000); //2 secs timeout 

if(fds[0].revents & POLLIN && ret > 0) 
{ 
    printf("event occur\n"); 
} 

Es scheint, die Warteschlange/Puffer ist nicht leer. Ich nehme nur an.

Was denkst du ist das Problem?

Danke.

Antwort

5

Wenn Sie ein POLLIN-Ereignis haben, was bedeutet "Es sind Daten zu lesen" - rufen Sie einige read() Funktion auf Ihrem fd vor poll() wieder auf?

+0

Danke, aber ich brauche diese Daten nicht zu lesen. Das Wichtigste für mich ist, dass es ein Ereignis gibt. Denkst du, ich muss das lesen? Gibt es eine Möglichkeit, den Puffer zu löschen? – domlao

+0

Ich denke, Sie müssen diese Daten lesen. –

+0

Ich sehe, danke, ich denke, das tun müssen. – domlao

11

Offensichtlich, wenn Sie eingehende Daten abfragen, sollten Sie verfügbare Daten konsumieren (Aufruf von read()) oder es wird immer noch da sein und die Umfrage wird sofort zurückkehren. Symmetrisch ist für POLLOUT eigentlich keine Operation notwendig, aber normalerweise möchten Sie so schnell wie möglich das nächste write() aufrufen. Also als Faustregel POLLIN -> lesen, POLLOUT -> schreiben.

Sie sollten auch Sie pollfd Struktur vor dem erneuten Aufruf der Umfrage zurücksetzen.

fds[0].fd = sck; 
fds[0].events = POLLIN; 
fds[0].revents = 0; 
ret = poll(fds, 1, 2000); //2 secs timeout 

if(fds[0].revents & POLLIN && ret > 0) 
{ 
    printf("event occur\n"); 
} 

Wenn Sie es nicht jedes Mal zurückgesetzt, Müll aus früherem Aufruf kann Umfrage Verhalten ändern (na ja, nicht wirklich, das ist nur eine Portabilität Ausgabe).

Im Produktionscode müssen Sie auch den Rückgabewert überprüfen, da die Abfrage möglicherweise aus einem anderen Grund als dem erwarteten Ereignis unterbrochen wurde (wie ein Signal). Dann möchten Sie es normalerweise wieder aufrufen, anstatt Daten zu lesen, die nicht verfügbar sind (zur Erinnerung, der Poll-Rückgabewert ist die Anzahl der Ereignisse, 0 Timeout, -1 ein Fehler, dessen Nummer in errno ist).

Fehler bei Dateideskriptoren, die zur Abfrage bereitgestellt werden, können ebenfalls auftreten. Sie führen nicht dazu, dass Poll einen Fehler zurückgibt, sondern setzen POLLERR, POLLHUP oder POLLNVAL im revent-Feld der pollfd-Struktur für diesen Dateideskriptor. Wenn diese Ereignisse gesetzt sind, ruft der Aufruf von read einige Fehlercodes auf, die Sie überprüfen können.

+0

danke. tatsächlich setze ich immer die Werte in meiner Struktur zurück, und ich denke, die beste Lösung ist, die verfügbaren Daten zu lesen. – domlao

+0

Danke, aber es scheint, dass ich einen Fehler in meinem Lesefunktionsaufruf bekomme, es scheint, dass es einen Wert -1 zurückgibt, das errno sagte, dass das Argument ungültig ist, aber ich bin sicher, dass die Parameter korrekt sind. – domlao

+0

Ich habe ein paar Zeilen zur Fehlerüberprüfung hinzugefügt. Das ist am wahrscheinlichsten, wenn Ihre erste Umfrage bei Timeout oder Fehler stoppt. Normalerweise benutze ich nach jeder Abfrage eine switch-Anweisung, um Fehler- und Zeitüberschreitungsfälle zu verwalten. Der Standardwert ist der normale Fall, in dem einige Ereignisse aufgetreten sind. Wie auch immer, wenn das Lesen fehlschlägt, sollte ein Fehler auftreten. Ist Ihr Dateideskriptor in Ordnung? Vielleicht geöffnet, fehlgeschlagen oder nicht zum Lesen, oder Datei wurde geschlossen ... nun, keine Notwendigkeit zu erraten, überprüfen Sie den Fehler. – kriss

4

Es wird empfohlen, vor dem Lesen des Dateideskriptors nach POLLHUP oder POLLNVAL zu suchen. Allerdings glaube ich, dass read() nur fehlschlagen würde, wenn das der Fall wäre, , wenn Abruf eines Dateideskriptors, der für längere Zeiträume zu blockieren erwartet, wie ein Modem. In diesem Fall würden Sie hängen (abhängig davon, was Sie an open() übergeben haben).

Sie sind wahrscheinlich nicht:

  • das Ereignis FD überhaupt vor dem nächsten poll() Lesen, oder,
  • alle verfügbaren Daten gelesen werden.

Wenn Sie die Struktur pollfd Array initialisiert vor poll() zu fordern, sollte es nicht sein ‚Müll‘ zu sprechen.

Dennoch ist es wahrscheinlich eine gute Idee, auch zu überprüfen und sicher zu sein, es gibt etwas, das es wert ist, read() vor dem Aufruf zu tun.

+0

Danke, ich habe die Daten gelesen, aber es scheint, dass der Lesevorgang einen Nullwert zurückgibt, was bedeutet, dass keine Daten gelesen werden. – domlao

+0

@sasayins, ist die FD so etwas wie ein Modem? Was genau suchst du? –

4

poll gibt Ihnen ein Ereignis, wenn Daten/Ereignisse zu lesen sind/Fehler/wenn Sie schreiben können.

Wenn Sie ein Ereignis erhalten, das sagt "Es gibt Daten zu lesen" und Sie nichts lesen - es wird immer noch "Daten zu lesen" beim nächsten Anruf poll und Sie erhalten ein anderes Ereignis.