2017-10-27 8 views
0

Ich bin ein wenig neu zu fifo s auf Linux und haben auch begrenzte Erfahrung mit select().Wie unterscheidet man Fifo Openable von lesbarem Inhalt?

Ich habe learned, dass das Aufrufen von open() auf dem Leseende eines FIFO blockiert, bis das Schreibende die Pipe beendet.

Man kann das Leseende des Fifos mit O_NONBLOCK öffnen, um nicht bei open() zu blockieren. Sie können dann select() mit dem fifo Dateideskriptor in den Readfds, um zu wissen, wann die Datei geöffnet werden kann - wahr?

Worüber ich jetzt verwirrt bin: Nachdem ich gewusst habe, dass die Datei geöffnet werden kann, möchte ich später wissen, dass der Fifo lesbaren Inhalt hat, dh ich würde gerne den read() über den Fifo-Dateideskriptor wissen würde nicht blockieren. Dazu hätte ich gedacht, select() mit dem FIFO-Datei-Deskriptor in den Readfds - aber dies scheint zu Konflikt mit der Verwendung von select() zu wissen, ob die Datei zu öffnen ist.

Also ich denke, meine Frage zusammenfassen: Wie kann ich select() nutzen zu wissen 1), wenn open() am gelesenen Ende eines Fifo würde nicht blockieren, und 2) wenn read() auf einem Fifo blockieren würde nicht?

Antwort

0

Meine Annahme, dass select() Entsperrungen auf dem Leseende, um anzuzeigen, dass der Fifo geöffnet werden kann, scheint falsch zu sein. Es sieht so aus, als ob select() auf dem Leseende nur dann freigibt, wenn im FIFO Daten zu lesen sind.

Dieser Testcode zeigt meine Beobachtung: wie ist die select() mal out; Kommentarzeichen für die einzelne kommentierte Zeile und select() entsperrt den Deskriptor der fifo-Datei.

#include <iostream> 
#include <pthread.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/select.h> 
#include <ctime> 

#define FIFO "/tmp/foo" 

void* sr1(void* arg) 
{ 
    mkfifo(FIFO, 0777); 
    sleep(3); 
    int fd = open (FIFO, O_WRONLY); 
    //write(fd, "a", 1); 
    std::cout << "t1 opened " << fd << std::endl; 
    sleep(3); 
    close(fd); 
    std::cout << "t1 closed " << fd << std::endl; 
    return NULL; 
} 

void* sr2(void* arg) 
{ 
    int fd = open(FIFO, O_RDONLY | O_NONBLOCK); 
    std::cout << "t2 opened " << fd << std::endl; 
    fd_set readfds; 
    FD_ZERO(&readfds); 
    FD_SET(fd, &readfds); 
    struct timeval ts = { 5, 0 }; 
    std::cout << "t2 waiting now" << std::endl; 
    select(fd + 1, &readfds, NULL, NULL, &ts); 
    if (FD_ISSET(fd, &readfds)) 
    { 
    std::cout << "t2 " << fd << " set so select() unblocked" << std::endl; 
    } 
    else 
    { 
    std::cout << "t2 " << " select() unblocked at timeout" << std::endl; 
    } 
    close(fd); 
    std::cout << "t2 closed " << fd << std::endl; 
    return NULL; 
} 

int main(int argc, char* argv[]) 
{ 
    pthread_t t1; 
    pthread_t t2; 

    pthread_create(&t1, NULL, sr1, NULL); 
    pthread_create(&t2, NULL, sr2, NULL); 

    pthread_join(t1, NULL); 
    pthread_join(t2, NULL); 
} 
Verwandte Themen