2016-08-05 55 views
0

Ich habe ein Problem mit Pthread Abbruch und mit Cleanup-Handler. In der POSIX-Bibliothek gibt es zwei Funktionen: pthread_cleanup_push und pthread_cleanup_pop. Das Problem ist, dass sie keine Funktionen sind, sondern Makros! Darüber hinaus scheint es, dass sie in Paaren platziert werden müssen, d. H. Für jeden Push, muss auch Pop sein. Aber ich finde es etwas merkwürdig.pthread_cancel() und Verwendung von Bereinigungshandlern.

Angenommen, ich solche Code-Struktur haben:

{ 
    pthread_mutex_lock(&mutex); 
    pthread_cleanup_push(cleanup_mutex, &mutex); 

    // any code that can be cancellation point 

    while(/*some condition *) { 
     // any code that cancellation point 

     // 1. signaled -> thread given mutex 
     // 2. timeout -> thread given mutex 
     // 3. canceled -> thread given mutex and than cleanup handlers 
     if(pthread_cond_timedwait(&cond, &mutex, &abstimeout) == ETIMEDOUT) { 

      /*** HERE SHOULD BE pthread_cleanup_pop(0)! But it cannot be placed! case 2)***/ 
      pthread_mutex_unlock(&mutex); 
      return NULL; 
      } 
     } 
     // any code that can be cancellation point 

     // consume something 

     // any code that can be cancellation point 

     pthread_cleanup_pop(0); // takes care of case 1) 
     pthread_mutex_unlock(&mutex); 

     return something; 

    } 
+0

Gibt es da eine Frage? – EOF

Antwort

1

Ja, es ist ein wenig seltsam, aber das ist, wie es ist. Im schlimmsten Fall können Sie eine goto verwenden, um zu einer return Anweisung im entsprechenden Bereich zu springen. Aber es gibt normalerweise einen natürlicheren Weg, es zu tun.

+0

yeah goto helfen. Ich platziere statt pthread_mutex_unlock(); zurückgeben NULL; die goto-Anweisung wie folgt: goto UNLOCK_AND_RETURN; und dann vor diesem pthread_cleanup_pop (0); pthread_mutex_unlock (& ​​mutex); Ich habe Label UNLOCK_AND_RETURN platziert: Es scheint sehr elegant zu sein –