Problem mit pthread_cond_timedwait

Dieses Thema im Forum "Mac OS X Entwickler, Programmierer" wurde erstellt von der_Kay, 12.09.2006.

  1. der_Kay

    der_Kay Thread Starter MacUser Mitglied

    Beiträge:
    1.693
    Zustimmungen:
    7
    MacUser seit:
    02.09.2004
    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...

    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)


    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;
    }
     
  2. DeineMudda

    DeineMudda unregistriert

    Beiträge:
    859
    Zustimmungen:
    72
    MacUser seit:
    12.05.2005
    Huhu,

    ich vermute, dass abstime Dein Problem ist. Bin mir nicht sicher, aber hier muss wohl eine Zeit, keine Dauer angegeben werden, zumindest steht in man:

    Gruß
    DeineMudda
     
  3. der_Kay

    der_Kay Thread Starter MacUser Mitglied

    Beiträge:
    1.693
    Zustimmungen:
    7
    MacUser seit:
    02.09.2004
    Genau das ist die Ursache. Danke Dir! :)
     
Die Seite wird geladen...

Diese Seite empfehlen