2016-05-13 18 views
-1

Ich habe Mutex-Sperren und Conditional Variable Locks in C erfolgreich implementiert und versuchen, das gleiche mit Semaphor zu erreichen. Unten ist mein Code, aber beim Ausführen ist die Ausgabe immer 24 statt 12. Hilf mir zu verstehen, wie man Semaphore benutzt.Verständnis Semaphore in C

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <semaphore.h> 

#define NUM_THREADS 2 
#define TCOUNT 12 
#define COUNT_LIMIT 12 

int count = 0; 
sem_t sem; 

void *dum(void *t_id){ 
    long id = long(t_id); 
    for (int i = 0; i < TCOUNT; i++) { 
     sem_wait(&sem); 
     count++; 
     sem_post(&sem); 
     printf("In Dum(). Count :: %d. Thread :: %ld \n", count, id); 
    } 
    pthread_exit(NULL); 
} 

int main (int argc, char *argv[]) { 
    int i; 
    long t1=1, t2=2; 
    sem_init(&sem, 0, 1); 
    pthread_t threads[NUM_THREADS]; 
    pthread_create(&threads[1], NULL, dum, (void *)t1); 
    pthread_create(&threads[2], NULL, dum, (void *) t2); 
    for (i=1; i<=2; i++) { 
     pthread_join(threads[i], NULL); 
    } 
    printf ("Main(): Waited on %d threads. Done.\n", NUM_THREADS); 
    printf ("Count should be 12. Actual Count: %d. \n", count); 
    pthread_exit(NULL); 
} 

Ausgang:

In Dum(). Count :: 1. Thread :: 1 
In Dum(). Count :: 2. Thread :: 1 
In Dum(). Count :: 3. Thread :: 1 
In Dum(). Count :: 4. Thread :: 1 
In Dum(). Count :: 5. Thread :: 1 
In Dum(). Count :: 6. Thread :: 1 
In Dum(). Count :: 7. Thread :: 1 
In Dum(). Count :: 8. Thread :: 1 
In Dum(). Count :: 9. Thread :: 1 
In Dum(). Count :: 10. Thread :: 1 
In Dum(). Count :: 11. Thread :: 1 
In Dum(). Count :: 13. Thread :: 1 
In Dum(). Count :: 13. Thread :: 2 
In Dum(). Count :: 14. Thread :: 2 
In Dum(). Count :: 15. Thread :: 2 
In Dum(). Count :: 16. Thread :: 2 
In Dum(). Count :: 17. Thread :: 2 
In Dum(). Count :: 18. Thread :: 2 
In Dum(). Count :: 19. Thread :: 2 
In Dum(). Count :: 20. Thread :: 2 
In Dum(). Count :: 21. Thread :: 2 
In Dum(). Count :: 22. Thread :: 2 
In Dum(). Count :: 23. Thread :: 2 
In Dum(). Count :: 24. Thread :: 2 
Main(): Waited on 2 threads. Done. 
Count should be 12. Actual Count: 24. 
+0

Übrigens, Sie haben einen Programmfehler in Ihrem Programm ... Sie müssen die Indizes 0 und 1 anstelle von 1 und 2 verwenden. Sie haben Glück, dass es nicht abstürzt, obwohl es Sie möglicherweise unvorhersehbar macht Verhalten. – kcraigie

+0

Nicht verwandt: 'lange ID = lang (t_id);'? Vielleicht ist mein C-Compiler ein bisschen * zu * alt. Habe ich ein anderes Memo verpasst, weil clang 3.8 compiling C11 kotzt. – WhozCraig

+0

Related: Sie haben zwei Threads, die für 12 Iterationen ** ** hart ** codiert sind. Auf die eine oder andere Weise, so lange Ihr Semaphor seine Arbeit macht, werden Sie mit insgesamt 24 Schritten zwischen den beiden enden. Wenn das nicht beabsichtigt ist, dann ist der Code falsch. Hinweis: 'COUNT_LIMIT' ist verdächtig definiert, aber im geposteten Code nicht verwendet. – WhozCraig

Antwort

1

Wie kcraigie gesagt, du die Fäden Array falsch sind Indizierung. Auch wäre es besser, zu T1 und T2 durch Zeiger übergeben:

void *dum(void *t_id) 
{ 
    long id = *(long*)t_id; 

und

pthread_create(&threads[0], NULL, dum, (void *) &t1); 
pthread_create(&threads[1], NULL, dum, (void *) &t2); 
for (i=0; i<2; i++) 
{ 
    pthread_join(threads[i], NULL); 
} 

auch in Ihrem Thread Sie sperren die Semaphore, erhöhe Zähler und lassen Sie die Semaphore, und dann können Sie drucken. Es gibt keine Garantie, dass der Wert, den Sie ausdrucken, der Wert der Zählung ist, nachdem Sie ihn inkrementiert haben. Der andere Thread könnte dies auch schon getan haben. Legen Sie das printf in das Semaphor-Lock:

Aber sonst 24 zu zählen scheint das richtige Verhalten zu sein. Sie haben zwei Schleifen, die über 2 Threads verteilt sind, die jeweils 12-mal iterieren und einen zum Zählen hinzufügen. Die Tatsache, dass einer der beiden die Schleife zuerst und dann der andere beendet, liegt vermutlich daran, dass der zuerst gestartete Thread seine gesamte Arbeit in einem einzigen Zeitfenster erledigt, bevor der Hauptthread Thread 2 gestartet hat.

+0

Was ich fragen ist, beide Threads sollten die Funktion dum() ausführen und der letzte Zählwert muss nur 12 sein. Warum? wenn es nur ein Thread ist, ist Ausgabe 12. Aber mit beiden Threads in Position mit Semaphor-Sperre, sollte es auch 12 rechts sein? sagen t1 wird bis 6 zählen und t2 muss es von 6 aufnehmen und bis 12 zählen. – Spark

+0

Mein Code könnte falsch sein, können Sie es bearbeiten – Spark

+0

Beide Threads Schleife TCOUNT mal. Der sem_wait übernimmt den Semaphor, der sem_post den Semaphor. Der Besitz des Semaphors nach sem_wait bewirkt nicht, dass der andere Thread eine Iteration seiner for-Schleife überspringt. Es bedeutet einfach, dass jeder andere Thread, der sem_wait aufruft, stoppt, bis sem_post aufgerufen wurde. – bazza