Thread aus recv() aufwecken



  • Hallo,

    ich habe eine Frage die ihr mir sicherlich recht schnell beantworten könnt.

    Folgendes Problem:

    Ich habe einen Thread in meiner Applikation der sich um die Netzwerkaufgaben kümmert. Dieser hängt in recv() fest. Ich will jetzt nicht recv() auf "nicht blockierend" umstellen, sondern den Thread aus diesem wartenden Zustand anhand eines Signals aufwecken.

    Das heißt ich will am besten mit pthread_cond_signal() ihn aus dem blockierenden Zustand raus bringen. Bin natürlich auch für andere Vorschläge offen.

    Schonmal danke im voraus.



  • Der Weg ist:

    1. Eine Pipe zwischen Benachrichtiger und Benachrichtigten öffnen.
    2. Per select auf die Pipe und das Netzwerk warten.
    3. Etwas in die Pipe schreiben, um zu benachrichtigen.



  • Wunderbar, das ist eine gute Lösung. Hab mich zwar noch nie mit Pipes auseinander gesetzt, aber Zeit wirds! 🙂



  • So, ich hab grad ein kleines Testtool geschrieben welches ich einfach nicht zum laufen bekomme.

    Der Netzwerkthread connected sich wunderbar zum Server. Danach geh ich mit diesem Socket und einer Pipe ins select() über. Der Server sendet daraufhin alle 10 Sekunden eine Message (via TCP).
    Doch der Networkthread bleibt einfach im select() hängen, ohne zurück zu kommen, weder bei einer Nachricht vom Server, noch bei einer Nachricht über die Pipe.

    Hier mal ein Codeschnippsel

    fd_set read_fds;
      FD_ZERO(&read_fds);
      FD_SET(m_sd, &read_fds); // m_sd ist der Filedescriptor vom Socket
      FD_SET(m_fd, &read_fds); // m_fd ist der Filedescriptor von der Pipe
    
      int nbr_fds;
      if((nbr_fds = select(2, &read_fds, NULL, NULL, NULL)) < 1)
      {
        exit(EXIT_FAILURE);
      }
      // hier kommt er nie an, select() returned nie...
    

    Der Server meldet auch keine Fehler beim senden. Also was mache ich falsch? Oder liegt der Fehler wo anders?



  • du musst bei select() nicht die anzahl der filedeskriptoren übergeben, sondern den wert (n filedeskriptor is ja in dem fall ein int) des höchsten filedeskriptors + 1.
    in deinem fall langt so was:

    int max = (m_sd > m_fd ? m_sd: m_fd) + 1;
    

    und dann halt

    if((nbr_fds = select(max, &read_fds, NULL, NULL, NULL)) < 1)
    {
        exit(EXIT_FAILURE);
    }
    


  • Hi,

    leider hast du keinen kompletten Source Code geschickt, so dass ich
    meine Vermutung nicht ausprobieren kann.

    Wenn du dir die Manpage zu select anschaust findest du folgendes:

    int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    ...
    n entspricht der Zahl des am höchsten nummerierten Datei-Deskriptors in allen drei Mengen, plus 1.

    Ich bin jetzt nicht sicher, welche Nummern deine Filedescriptoren für pipe
    und socket haben. Du mußt wohl das Maximum der beiden nehmen und eins dazu
    addieren.

    Kannst ja mal sagen, ob das geholfen hat. Ansonsten bitte ich dich,
    den für dieses Problem kompletten Code uns zur verfügung zu stellen.

    Gruß mcr



  • ok, ich war zu langsam. 😉



  • Oh man, das hab ich wirklich falsch verstanden. Ich dachte es wäre die Anzahl der FDs.
    Werde es gleich mal ausprobieren, aber das wird es sicher sein. Schonmal vielen Dank für die Hilfe!

    EDIT: Richtig, das wars... nochmal danke...


Anmelden zum Antworten