Socket in Thread soll beendet werden



  • Hallo zusammen,

    Ich habe ein kleines Socket Problem. Ich öffne in einem QThread einen Socket, der darauf wartet von einem externen System Daten zu empfangen. In meiner while-Schleife steht also:

    rt_dev_recvfrom(...)
    

    An dieser Stelle bleibt das Programm (bzw. der Thread) stehen und wartet auf den Input. Nun würde ich die Verbindung gerne von meiner GUI aus beenden und Sie später mit anderen Einstellungen neu zu starten. Ich weiß nur nicht wie. Ich habe inzwischen erfahren das man Threads besser nicht terminaten sollte. Außerdem funktioniert das auch nicht (also das erneute starten).
    Als nächstes wollte ich es mit Flags probieren. Aber das klappt ja nicht, weil ich das Flag nicht abfragen würde bevor nicht irgendwas empfange.

    Dank und Gruß,
    flambert



  • Socket nonblocking setzen und kurzen wait mit usleep
    AUs gui ein pthread_cancel wäre so ne Idee



  • if you want it to be efficient and only for Linux (2.6+) you could use

    int flags = 0;
    #ifdef EFD_CLOEXEC
    flags |= EFD_CLOEXEC;
    #endif
    #ifdef EFD_NONBLOCK
    flags |= EFD_NONBLOCK;
    #endif
    int efd = eventfd(0, flags);
    if (efd < 0) {
      perror("eventfd");
      return -1;
    }
    
    // in dem thread:
    int epoll_fd = epoll_create(2);
    if (epoll_fd < 0) {
      perror("epoll_create");
      return -1;
    }
    
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = sock; // Dein Socket!
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1) {
      perror("epoll_ctl: sock");
      return -1;
    }
    
    ev.events = EPOLLIN;
    ev.data.fd = efd;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, efd, &ev) == -1) {
      perror("epoll_ctl: efd");
      return -1;
    }
    
    #define MAX_EVENTS 10
    
    for (;;) {
      int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
      if (nfds == -1) {
        perror("epoll_wait");
        return -1;
       }
    
       for (int n = 0; n < nfds; ++n) {
         if (events[n].data.fd == sock) {
           // Mach hier das was du normalerweise machen würdest! Also recvfrom etc. aufrufen
         }
         else if(events[n].data.fd == efd) {
           uint64_t tmp;
           if(read(efd, &tmp, sizeof(tmp)) < 0) {
             perror("read");
           }
           // Zeit zum abbrechen!
           return 0;
         }
       }
    }
    
    // hier in deinem GUI Thread, um den anderen Thread zum stoppen zu bringen
    uint64_t tmp = 1;
    if(write(efd, &tmp, sizeof(tmp)) < 0) {
      perror("write");
    }
    

    @pferdefreund
    dann lieber epoll oder select mit einem timeout



  • MastorDisastor schrieb:

    if you want it to be efficient and only for Linux (2.6+) you could use

    😃 weiß nicht warum ich auf einmal auf englisch geschrieben habe. Gehirn noch ein bisschen eingeschlafen. Tschuldigung 😃

    "Wenn du es effizient und nur für Linux (2.6+) haben willst, könntest du:"



  • Du kannst den Socket auch einfach außerhalb des Threads schließen (natürlich muss der Socket dazu außerhalb des Threads bekannt sein), dann kehrt recv() zurück.


Log in to reply