/* Stolen and edited, with utmost gratitude, from: http://grace.evergreen.edu/~sherri/sos/concurrency/secondEdition/chap14/maincriticalsem.c */ #include #include #include #include #include #include #include #define TEN_MILLION 10000000L #define BUFSIZE 1024 void *threadout(void *args) { char buffer[BUFSIZE]; char *c; sem_t *semlockp; struct timespec sleeptime; semlockp = (sem_t *)args; sleeptime.tv_sec = 0; sleeptime.tv_nsec = TEN_MILLION; snprintf(buffer, BUFSIZE, "This is a thread from process %ld\n", (long)getpid()); c = buffer; /****************** entry section *******************************/ /* Now we create a mutual exclusion semaphore to make it right: */ while (sem_wait(semlockp) == -1) /* Entry section */ if(errno != EINTR) { fprintf(stderr, "Thread failed to lock semaphore\n"); return NULL; } /****************** start of critical section *******************/ while (*c != '\0') { fputc(*c, stderr); c++; nanosleep(&sleeptime, NULL); } /****************** exit section ********************************/ if (sem_post(semlockp) == -1) /* Exit section */ fprintf(stderr, "Thread failed to unlock semaphore\n"); /****************** remainder section ***************************/ return NULL; } int main(int argc, char *argv[]) { int error; int i; int n; sem_t semlock; pthread_t *tids; if (argc != 2){ /* check for valid number of command-line arguments */ fprintf (stderr, "Usage: %s numthreads\n", argv[0]); return 1; } n = atoi(argv[1]); tids = (pthread_t *)calloc(n, sizeof(pthread_t)); if (tids == NULL) { perror("Failed to allocate memory for thread IDs"); return 1; } if (sem_init(&semlock, 0, 1) == -1) { perror("Failed to initialize semaphore"); return 1; } for (i = 0; i < n; i++) if (error = pthread_create(tids + i, NULL, threadout, &semlock)) { fprintf(stderr, "Failed to create thread:%s\n", strerror(error)); return 1; } for (i = 0; i < n; i++) if (error = pthread_join(tids[i], NULL)) { fprintf(stderr, "Failed to join thread:%s\n", strerror(error)); return 1; } return 0; }