#include #include #include #include #include #include #include // this class is passed to all threads, acts as shared memory class Parameters{ public: int *arr; int size; pthread_mutex_t mutex; sem_t finished; }; // this function is where the thread starts void* thread(void* pParam) { Parameters *p = ((Parameters*)pParam); // wait for mutex, then print and sleep inside the critical section pthread_mutex_lock(&p->mutex); printf ("Thread %u started\n", pthread_self()); sleep (10); pthread_mutex_unlock(&p->mutex); // signal that this thread has exitted sem_post(&p->finished); pthread_exit(NULL); } int main(void) { Parameters p; // size of the array passed to threads p.size = 10; // initialize array p.arr = new int [p.size]; // create a mutex for accessing critical section (including printf) pthread_mutex_init(&p.mutex, NULL); // create semaphore that counts the number of active threads if( sem_init(&p.finished, 0, 0) != 0 ) printf("sem_init error:%d\n", strerror(errno)); // thread handles are stored here pthread_t threads[2]; // set thread creation attributes so that they can be joined pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // get current time time_t cur_time; time(&cur_time); // create the threads, structure p is the shared space between the threads for( int i = 0; i<2; i++ ){ int rc = pthread_create(&threads[i], NULL, thread, (void*)&p); if( rc ){ printf("pthread_create error: %d\n", rc); exit(-1); } } pthread_attr_destroy(&attr); // wait until the semaphore is incremented by each thread for( int i = 0; i<2; i++ ){ if( sem_wait(&p.finished) != 0 ) printf("sem_wait error:%d\n", errno); } // wait for all threads to exit for( int i = 0; i<2; i++ ){ int rc = pthread_join(threads[i], NULL); if( rc ){ printf("error in pthread_join:%d\n", rc); exit(-1); } } printf("all threads joined\n"); // clean up mutex and semaphore pthread_mutex_destroy(&p.mutex); sem_destroy(&p.finished); printf ("Terminating main(), completion time %d seconds\n", time(NULL)-cur_time); return 0; }