オペレーティングシステムの実験-生産者と消費者の問題


問題のように
/**
 * @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; }