#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <semaphore.h> // Windows#ifdef _WIN32#ifndef WIN32#define WIN32#endif#endif#ifdef WIN32#include <time.h>#include <windows.h>#define GET_TIME(t) t=clock()#define SLEEP(millis) Sleep(millis)#pragma comment(lib, "pthreadVC2.lib")// Mac OS X & Linux#else#include <sys/time.h>#include <unistd.h>timeval tValue;#define GET_TIME(t) gettimeofday(&tValue,0),t=(tValue.tv_sec*1000+tValue.tv_usec/1000)#define SLEEP(millis) usleep(1000*(millis))#endiftypedef int BufferType;typedef int ResultType;#define ACTION_FAILED 0#define ACTION_SUCCESSFUL 1#define BUFFER_SIZE 10BufferType buffer[BUFFER_SIZE];int currentSize=0;int currentIndex=0;ResultType insertItem(BufferType item){ return currentSize<BUFFER_SIZE ? (buffer[(currentIndex + currentSize++) % BUFFER_SIZE] = item, ACTION_SUCCESSFUL) : ACTION_FAILED;}ResultType removeItem(BufferType* item){ return ((currentSize > 0) && buffer[currentIndex] == *item) ? (--currentSize, ++currentIndex %= BUFFER_SIZE, ACTION_SUCCESSFUL) : ACTION_FAILED;}pthread_mutex_t mutex;sem_t full, empty;clock_t threadStartTime;int pId = 0;int cId = 0;#define P_TIME_SPAN_MAX 5000void* producer(void *params){ int id = pId++; while(true) { SLEEP((rand() % P_TIME_SPAN_MAX)); BufferType bufferItem = rand(); long beginTime, endTime; GET_TIME(beginTime); printf("%ld:\t Producer %d\t produced %d\n", (long)(beginTime - threadStartTime), id, bufferItem); sem_wait(&empty); pthread_mutex_lock(&mutex); (GET_TIME(endTime), insertItem(bufferItem) == ACTION_SUCCESSFUL) ? printf("%ld:\t Producer %d\t have put %d\t after %d\t milliseconds\n", endTime - threadStartTime, id, bufferItem, endTime - beginTime) : printf("%ld:\t Producer %d\t Report Error!\n", endTime - threadStartTime, id); pthread_mutex_unlock(&mutex); sem_post(&full); }}#define C_TIME_SPAN_MAX 5000void* consumer(void* params){ int id = cId++; while(true) { SLEEP((rand() % C_TIME_SPAN_MAX)); long beginTime, endTime; GET_TIME(beginTime); printf("%ld:\t Consumer %d\t want to consume\n", (long)(beginTime - threadStartTime), id); sem_wait(&full); pthread_mutex_lock(&mutex); BufferType bufferItem = buffer[currentIndex]; (GET_TIME(endTime), removeItem(&bufferItem) == ACTION_SUCCESSFUL) ? printf("%ld:\t Consumer %d\t consumed %d\t after %d\t milliseconds\n", endTime - threadStartTime, id, bufferItem, endTime - beginTime) : printf("%ld:\t Consumer %d\t Report Error!\n", endTime - threadStartTime, id); pthread_mutex_unlock(&mutex); sem_post(&empty); }}int main(int argc, char* argv[]){ srand(time(0)); pthread_mutex_init(&mutex, NULL); sem_init(&full, 0, 0); sem_init(&empty, 0, BUFFER_SIZE); int sleepTime = 0; int producerCount = 0; int consumerCount = 0; if (argc == 4) { sscanf(argv[1], "%d", &sleepTime); sscanf(argv[2], "%d", &producerCount); sscanf(argv[3], "%d", &consumerCount); } else { printf("Input sleep time before terminating:"); scanf("%d", &sleepTime); printf("Input producer number:"); scanf("%d", &producerCount); printf("Input consumer number:"); scanf("%d", &consumerCount); } GET_TIME(threadStartTime); int i; for (i = 0; i < producerCount; i++) { pthread_t pid; pthread_create(&pid, NULL, producer, NULL); } for (i = 0; i < consumerCount; i++) { pthread_t pid; pthread_create(&pid, NULL, consumer, NULL); } SLEEP(sleepTime); printf("End of time\n"); return 0;}