This is the assignment I'm working on. It should use semaphores, not a mutex.
#include <stdio.h> #include <pthread.h> #include <assert.h> #include <unistd.h> #include <semaphore.h> #include <fcntl.h> sem_t *ab, *ac, *ad, *de, *ce, *bf, *ef; void *a(void *arg) { printf("Entering A...\n"); sleep(1); printf("Exiting A...\n"); assert(sem_post(ab)==0); assert(sem_post(ac)==0); assert(sem_post(ad)==0); pthread_exit((void *)99); } void *b(void *arg) { assert(sem_wait(ab)==0); printf("Entering B...\n"); sleep(1); printf("Exiting B...\n"); assert(sem_post(bf)==0); pthread_exit((void *)99); } void *c(void *arg) { assert(sem_wait(ac)==0); printf("Entering C...\n"); sleep(1); printf("Exiting C...\n"); assert(sem_post(ce)==0); pthread_exit((void *)99); } void *d(void *arg) { assert(sem_wait(ad)==0); printf("Entering D...\n"); sleep(1); printf("Exiting D...\n"); assert(sem_post(de)==0); pthread_exit((void *)99); } void *e(void *arg) { assert(sem_wait(ce)==0); assert(sem_wait(de)==0); printf("Entering E...\n"); sleep(1); printf("Exiting E...\n"); assert(sem_post(ef)==0); pthread_exit((void *)99); } void *f(void *arg) { assert(sem_wait(bf)==0); assert(sem_wait(ef)==0); printf("Entering F...\n"); sleep(1); printf("Exiting F...\n"); pthread_exit((void *)99); } int main() { pthread_t _a, _b, _c, _d, _e, _f; int r1, r2, r3, r4, r5, r6; ab=sem_open("foobar", O_CREAT, 0700, 0); ac=sem_open("foobar", O_CREAT, 0700, 0); ad=sem_open("foobar", O_CREAT, 0700, 0); ce=sem_open("foobar", O_CREAT, 0700, 0); de=sem_open("foobar", O_CREAT, 0700, 0); ef=sem_open("foobar", O_CREAT, 0700, 0); bf=sem_open("foobar", O_CREAT, 0700, 0); /*sem_init(ab,0,1); sem_init(ac,0,1); sem_init(ad,0,1); sem_init(ce,0,1); sem_init(de,0,1); sem_init(ef,0,1); sem_init(bf,0,1);*/ assert(pthread_create(&_a, NULL, a, &r1) == 0); assert(pthread_create(&_b, NULL, b, &r2) == 0); assert(pthread_create(&_c, NULL, c, &r3) == 0); assert(pthread_create(&_d, NULL, d, &r4) == 0); assert(pthread_create(&_e, NULL, e, &r5) == 0); assert(pthread_create(&_f, NULL, f, &r6) == 0); assert(pthread_join(_a, NULL) == 0); assert(pthread_join(_b, NULL) == 0); assert(pthread_join(_c, NULL) == 0); assert(pthread_join(_d, NULL) == 0); assert(pthread_join(_e, NULL) == 0); assert(pthread_join(_f, NULL) == 0); assert( sem_close(ab)==0 ); assert( sem_close(ac)==0 ); assert( sem_close(ad)==0 ); assert( sem_close(ce)==0 ); assert( sem_close(de)==0 ); assert( sem_close(bf)==0 ); assert( sem_close(ef)==0 ); return 0; }
This is pretty simple, but for some reason it is not running in the correct order. The conclusion is far from consistent, but always incorrect. Here is one example:
Entering A ...
Entering B ... <---- sem_post (ab) has not yet been called
Exit ... Enter C ...
Entering D ...
Exit ... Exit ... Exit ... Enter E ...
Entering F ...
Output F ...
Exit E ...
He should follow this diagram:

Any help with this would be greatly appreciated, but itβs an appointment, so donβt start telling me to do it in a completely different way and not give the answer directly, just point me in the right direction.