现在的位置: 首页 > 综合 > 正文

生产者与消费者问题

2012年12月27日 ⁄ 综合 ⁄ 共 3009字 ⁄ 字号 评论关闭
#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;
}

抱歉!评论已关闭.