操作系统实验——生产者与消费者问题

如题

/**
 * @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\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 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\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;
}

你可能感兴趣的:(windows,linux,pthread)