Problem mit pthread_cond_timedwait

Diskutiere Problem mit pthread_cond_timedwait im C/C++ Forum im Bereich Programmieren unter Linux/Unix; Hallo zusammen, ich habe beim Aufruf von pthread_cond_timedwait das Problem, dass die Funktion sofort mit ETIMEOUT zurückkehrt; egal was als...

  1. #1 der_Kay, 12.09.2006
    der_Kay

    der_Kay Doppel-As

    Dabei seit:
    28.02.2006
    Beiträge:
    140
    Zustimmungen:
    0
    Hallo zusammen,

    ich habe beim Aufruf von pthread_cond_timedwait das Problem, dass die Funktion sofort mit ETIMEOUT zurückkehrt; egal was als tatsächlicher Timeout-Wert angegeben wird.

    Untenstehender Code setzt einen Signalhandler für INTERRUPTED (= CTRL-C), startet einen Thread ("server") und pausiert dann. Beim Eintreffen eines SIGINT soll der Signalhandler durch Ändern einer globalen Variablen (g_i_server_run) die Server-Schleife beenden und dann auf die Condition (g_cond_t_stop) warten. Funktioniert erwartungsgemäß, wenn ohne timeout mit pthread_cond_wait gewartet wird; nur pthread_cond_timedwait wird irgendwie ignoriert.

    Die Präprozessordirektiven _TIMEDWAIT, SECONDS_2_W8 und SHUTDOWN_DELAY steuern das Beenden des Threads und Anwedung: Wenn _TIMEDWAIT definiert ist, wird pthread_cond_timedwait zum Warten auf die Beendigung des Threads verwendet. Der Hauptthread wartet innerhalb des Signalhandlers SECONDS_2_W8 lang darauf, dass der Serverthread die Condition signalisiert. Der Serverthread tut das mit der Verzögerung SHUTDOWN_DELAY.

    Wenn also SHUTDOWN_DELAY echt größer SECONDS_2_W8 gewählt wird, sollte schliesslich nach Ablauf der Wartezeit ein ETIMEOUT auftreten. Genau das passiert nicht.

    Ich konnte keinen offensichtlichen Fehler in meinem Code finden; was mach ich verkehrt? Ist der Signalhandler das Problem? Habe mal herumgesucht und es scheint, dass pthread_cond_timedwait gern mal buggy ist...

    Code hängt unten als ZIP dran.

    Meine Umgebung:
    sw_vers
    ProductName: Mac OS X
    ProductVersion: 10.4.7
    BuildVersion: 8J135

    gcc -v
    Using built-in specs.
    Target: powerpc-apple-darwin8
    Configured with: /private/var/tmp/gcc/gcc-5247.obj~4/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --build=powerpc-apple-darwin8 --host=powerpc-apple-darwin8 --target=powerpc-apple-darwin8
    Thread model: posix
    gcc version 4.0.1 (Apple Computer, Inc. build 5247)

    (ja, ist ein Mac, passierte aber auch unter SuSE 10.1)


    Vielen Dank fürs Draufschauen,

    Kay

    PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <errno.h>
    #include <unistd.h>
    #include <time.h>
    #include <pthread.h>

    /* Auskommentieren für unbegrenztes Warten */
    /* #define _TIMEDWAIT */

    /* Wartezeit */    
    #define SECONDS_2_W8    10

    /* Server shutdown delay in Sekunden    */
    #define SHUTDOWN_DELAY    2

    int                g_i_server_run;
    pthread_t    g_pthread_t_server;
    pthread_mutex_t    g_mutex_t_run;
    pthread_cond_t    g_cond_t_stop;

    #define __TEST_EXIT(cmd)    if ( 0 != (errcode = (cmd))) {            \
        
    fprintf (stderr"%s:%d:%s->%s\n"__FILE____LINE__,#cmd,        \
                 
    strerror(errcode)); exit(1);}

    void sigint_handler_shutdown( )
    {
        
    int errcode;
        
    sigset_t mask_set;
        
    struct timespec ts;
        
        
    ts.tv_sec=SECONDS_2_W8;
        
    ts.tv_nsec=0;
        
        
    signal(SIGINTsigint_handler_shutdown);
        
    sigfillset(&mask_set);
        
    sigprocmask(SIG_SETMASK, &mask_setNULL);
        
        
    /* shutdown http server */
        
    g_i_server_run 0;
        
    fprintfstdout"shutdown server...");
        
    fflush(stdout);
        
    #ifdef _TIMEDWAIT               
        
    __TEST_EXIT(pthread_cond_timedwait (&g_cond_t_stop, &g_mutex_t_run, &ts ))
    #else
        
    __TEST_EXIT(pthread_cond_wait (&g_cond_t_stop, &g_mutex_t_run ))
    #endif
        
        
    fprintf(stdout"ok.\n");
        exit(
    0);
    }

    voidserver_routinevoidp_arg )
    {
        
    int errcode;
        
        while ( 
    g_i_server_run )
        {
            
    printf(".");
            
    fflush (stdout );
            
    sleep1) ;
        }
        
        
    /* merklich verzögern */
        
    sleepSHUTDOWN_DELAY ) ;
        
        
    __TEST_EXIT(pthread_cond_signal(&g_cond_t_stop));
        
        return 
    NULL;
    }

    int main (int argcchar** argv )
    {
        
    int errcode;
        
        if( 
    SIG_ERR == sigset(SIGINTsigint_handler_shutdown))
        {
            
    fprintfstderr"%s: %d sigset(): %s.\n"
                     
    __FILE____LINE__strerror(errno));
            exit(
    1);
        }
        
        
    g_i_server_run 1;
        
        
    /*    server mutex    */
        
    __TEST_EXIT(pthread_mutex_init(&g_mutex_t_runNULL ));
        
        
    /* condition */
        
    __TEST_EXIT(pthread_cond_init(&g_cond_t_stopNULL));

        
    /*    server mutex    */
        
    __TEST_EXIT(pthread_mutex_lock(&g_mutex_t_run));
        
        
    /*    start server    */
        
    fprintf(stdout"start server...");
        
    __TEST_EXIT(pthread_create(&g_pthread_t_serverNULL
                                   
    server_routineNULL));
        
        
    fprintf(stdout"ok\n");
        
    pause();
        
        
    /*    cleanup mutex & cond    */
        
    pthread_mutex_destroy( &g_mutex_t_run );
        
    pthread_cond_destroy( &g_cond_t_stop );
        
        return 
    0;
    }
     

    Anhänge:

  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. hwj

    hwj Doppel-As

    Dabei seit:
    23.06.2006
    Beiträge:
    131
    Zustimmungen:
    0
    Ort:
    Bei Buxtehude
    Ändere Zeile 33 in
    Code:
            ts.tv_sec=time((time_t*)0) + SECONDS_2_W8;
    
    Es wird keine relative Wartezeit sondern ein absoluter Zeitpunkt erwartet.

    Heiko
     
  4. #3 der_Kay, 12.09.2006
    der_Kay

    der_Kay Doppel-As

    Dabei seit:
    28.02.2006
    Beiträge:
    140
    Zustimmungen:
    0
    Allerherzlichsten Dank! :)
     
Thema:

Problem mit pthread_cond_timedwait

Die Seite wird geladen...

Problem mit pthread_cond_timedwait - Ähnliche Themen

  1. Netzwerkproblem ? , wo ud wie suchen

    Netzwerkproblem ? , wo ud wie suchen: Hallo Folgende Problem: Testserver ist i686 Debian-unstable , auf dem läuft primär der apt-proxy apt-cahcer ng. Zugriff im Moment nur per ssh....
  2. Verständnisproblem Samba / LDAP

    Verständnisproblem Samba / LDAP: Hallo zusammen! Ich habe unter Ubuntu 16.04 einen LDAP und Samba Server aufgesetzt. Diese scheinen auch ordnungsgemäß zu funktionieren, sodaß ich...
  3. nginx+php-fpm problem

    nginx+php-fpm problem: Moin, ich hab hier gerade ein Problem und keine Idee mehr woran es liegt. Ich muss wie schon in der Überschrift erwähnt nginx dazu bringen php...
  4. Problem mit Windows auf Ordner auf dem Linuxsystem zuzugreifen

    Problem mit Windows auf Ordner auf dem Linuxsystem zuzugreifen: Ich mache gerade meine ersten Schritte mit Linux und würde gerne auf Dateien meines Linuxsystems auch mit Windows zugreifen, ich bin am...
  5. Virtualboxproblem

    Virtualboxproblem: Hallo Folgnedes Problem: Ich kann ohne Probleme In Debian-Sid, 64Bit und virtualbox-dkms Unixoide installieren, wenn es sich um eine...