recv() beenden



  • Hi,
    Ich haben ein Server-Programm geschrieben (multithreaded) und habe jetzt folgendes Problem:
    mein Listen-Thread sieht in etwa so aus:

    while(!shutdown)
    {
    	char msg[BUFFERSIZE];
    	int status = recv(socket_fd, msg, sizeof(msg),0 ); // read message from client 
    
    	if(status <= 0) // client closed transmission or an error occured
    	{
                       //error-handling
     	}
    }
    

    nun möchte ich mit der Variable shutdown den Thread enden lassen, allerdings bleibt der immer beim recv hängen (was auch klar ist). Wie löse ich das am besten?
    Ein Timeout ist die letzte Wahl und mMn nicht sinvoll wenn ich 1sec oder länger darauf warten muss nachdem die Variable geändert wurde. Wenn ich die Zeit verkürze muss ich ständig ein keepalive-Signal senden was mir auch nicht wirklich gefällt.

    LG



  • Das Socket auf Nonblocking setzen.

    int flags = fcntl(fd, F_GETFL, 0);
    if(flags == -1) {
      flags = 0;
    }
    if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
      perror("fcntl");
      // ...
    }
    

    man: fcntl(2)



  • Daran habe ich auch gedacht, allerdings habe ich dann eine CPU-Auslastung von 90-100% was alles andere als gut ist.

    LG



  • Schläfer doch dein Programm für n Millisekunden ein.
    Sollte somit die Auslastung verbessern.

    Wird das nicht sonst auch so gehandhabt?



  • Sowas wie sleep(1) geht bei mir vielleicht als Hack durch, aber bestimmt nicht als saubere Lösung.

    Ich kann mir nicht ganz vorstellen das man das so macht...

    LG



  • select oder epoll



  • Setzt du shutdown in einem anderen Thread? Dann ist eine ungeschützte Abfrage ohnehin nicht sicher. Aber du könntest das Problem lösen, wenn du anstelle shutdown einfach eine pipe nimmst und dann zB mit epoll auf die pipe und das socket wartest. Wenn etwas auf dem socket kommt, dann kannst du einfach read aufrufen und wenn etwas bei shutdown kommt, dann machst du eben ein shutdown.



  • Applications can use an eventfd file descriptor instead of a pipe (see pipe(2)) in all cases where a pipe is used simply to signal events. The kernel overhead of an eventfd file descriptor is much lower than that of a pipe, and only one file descriptor is required (versus the two required for a pipe).



  • Danke,
    genau sowas habe ich gesucht.

    LG



  • 2.6.22 schrieb:

    Applications can use an eventfd file descriptor instead of a pipe (see pipe(2)) in all cases where a pipe is used simply to signal events. The kernel overhead of an eventfd file descriptor is much lower than that of a pipe, and only one file descriptor is required (versus the two required for a pipe).

    Oh danke. Man lernt immer was dazu. 👍

    man: eventfd(2)


Anmelden zum Antworten