オペレーティングシステムの実験-生産者と消費者の問題
問題のように
/**
* @file main.cpp
* @version 1.0.1
* @author
* @author Victor Zhang
* @date 2011-05-11
*/
#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))
#endif
typedef int BufferType;
typedef int ResultType;
#define ACTION_FAILED 0
#define ACTION_SUCCESSFUL 1
#define BUFFER_SIZE 10
BufferType 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 5000
void* 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
", (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
", endTime - threadStartTime, id, bufferItem, endTime - beginTime)
: printf("%ld:\t Producer %d\t Report Error!
", endTime - threadStartTime, id);
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
}
#define C_TIME_SPAN_MAX 5000
void* 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
", (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
", endTime - threadStartTime, id, bufferItem, endTime - beginTime)
: printf("%ld:\t Consumer %d\t Report Error!
", 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
");
return 0;
}