/***************************************************
*--------------------------------------------------
* Creat : 2001. 04. 10 (programed by Cori-Young )
* Site: http://www.byoneself.co.kr
* Update :
*--------------------------------------------------
* Compile : cc -o xxx xxx.c -lpthread -lrt
*--------------------------------------------------
* Machine hardware: sun4u
* OS version: 5.7
* Processor type: sparc
* Hardware: SUNW,Ultra-60
***************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#define _MULTI_THREADED
#define NTHREADS 2
static void checkResults(char *string, int rc) {
if (rc) {
printf("Error on : %s, rc=%d", string, rc);
exit(EXIT_FAILURE);
}
return;
}
int workToDo = 0;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *threadfunc(void *parm)
{
int rc;
while (1) {
/* Usually worker threads will loop on these operations */
rc = pthread_mutex_lock(&mutex);
checkResults("pthread_mutex_lock()n", rc);
while (!workToDo) {
printf("Thread blockedn");
rc = pthread_cond_wait(&cond, &mutex);
checkResults("pthread_cond_wait()n", rc);
}
printf("Thread awake, finish work!n");
/* Under protection of the lock, complete or remove the work */
/* from whatever worker queue we have. Here its simply a flag */
workToDo = 0;
rc = pthread_mutex_unlock(&mutex);
checkResults("pthread_mutex_lock()n", rc);
}
return NULL;
}
int main(int argc, char **argv)
{
int rc=0;
int i;
pthread_t threadid[NTHREADS];
printf("Enter Testcase - %sn", argv[0]);
printf("Create %d threadsn", NTHREADS);
for(i=0; i<NTHREADS; ++i) {
rc = pthread_create(&threadid[i], NULL, threadfunc, NULL);
checkResults("pthread_create()n", rc);
}
sleep(5); /* Sleep isn't a very robust way to serialize threads */
for(i=0; i<5; ++i) {
printf("Wake up a worker, work to do...n");
rc = pthread_mutex_lock(&mutex);
checkResults("pthread_mutex_lock()n", rc);
/* In the real world, all the threads might be busy, and */
/* we would add work to a queue instead of simply using a flag */
/* In that case the boolean predicate might be some boolean */
/* statement like: if (the-queue-contains-work) */
if (workToDo) {
printf("Work already present, likely threads are busyn");
}
workToDo = 1;
rc = pthread_cond_signal(&cond);
checkResults("pthread_cond_broadcast()n", rc);
rc = pthread_mutex_unlock(&mutex);
checkResults("pthread_mutex_unlock()n", rc);
sleep(5); /* Sleep isn't a very robust way to serialize threads */
}
printf("Main completedn");
exit(0);
return 0;
} |
|