2016-02-27 137 views
0

我正在处理生产者和消费者问题。生产者正在生成一个随机变量并将其放入缓冲区。完成此操作后,我想打印出缓冲区的内容。我也想在消费者从缓冲区中消耗一个变量后打印缓冲区的内容。所以只是作为一个例子,打印缓冲区内容

生产者线程34567834增加43到缓冲区,以及当前缓冲区包含7,29,43

我不知道的方法来打印缓冲区的内容于一体的printf ()语句。谢谢你的帮助。

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 


//Submit with screen shot of compiling and running code. 
#define SIZE 20 
#define NUMB_THREADS 10 
#define PRODUCER_LOOPS 10  
#define CONSUMER_LOOPS 2  

#define TRUE 1 
#define FALSE 0 

typedef int buffer_t; 
buffer_t buffer[SIZE]; 
int buffer_index; 

pthread_mutex_t buffer_mutex; 
/* initially buffer will be empty. full_sem 
    will be initialized to buffer SIZE, which means 
    SIZE number of producer threads can write to it. 
    And empty_sem will be initialized to 0, so no 
    consumer can read from buffer until a producer 
    thread posts to empty_sem */ 
sem_t full_sem; /* when 0, buffer is full */ 
sem_t empty_sem; /* when 0, buffer is empty. Kind of 
        like an index for the buffer */ 

/* sem_post algorithm: 
    mutex_lock sem_t->mutex 
    sem_t->value++ 
    mutex_unlock sem_t->mutex 

    sem_wait algorithn: 
    mutex_lock sem_t->mutex 
    while (sem_t->value > 0) { 
     mutex_unlock sem_t->mutex 
     sleep... wake up 
     mutex_lock sem_t->mutex 
    } 
    sem_t->value-- 
    mutex_unlock sem_t->mutex 
*/ 


void insertbuffer(buffer_t value) { 
    if (buffer_index < SIZE) { 
     buffer[buffer_index++] = value; 
    } else { 
     printf("Buffer overflow\n"); 
    } 
} 

buffer_t dequeuebuffer() { 
    if (buffer_index > 0) { 
     return buffer[--buffer_index]; // buffer_index-- would be error! 
    } else { 
     printf("Buffer underflow\n"); 
    } 
    return 0; 
} 


int isempty() { 
    if (buffer_index == 0) 
     return TRUE; 
    return FALSE; 
} 

int isfull() { 
    if (buffer_index == SIZE) 
     return TRUE; 
    return FALSE; 
} 

void *producer2(void *thread_n) { 
    int thread_numb = *(int *)thread_n; 
    buffer_t value; 
    int i=0; 
    while (i++ < PRODUCER_LOOPS) { 
     sleep(rand() % 10); 
     value = rand() % 100; 
     pthread_mutex_lock(&buffer_mutex); 
     do { 
      // cond variables do the unlock/wait and wakeup/lock atomically, 
      // which avoids possible race conditions 
      pthread_mutex_unlock(&buffer_mutex); 
      // cannot go to slepp holding lock 
      sem_wait(&full_sem); // sem=0: wait. sem>0: go and decrement it 
      // there could still be race condition here. another 
      // thread could wake up and aqcuire lock and fill up 
      // buffer. that's why we need to check for spurious wakeups 
      pthread_mutex_lock(&buffer_mutex); 
     } while (isfull()); // check for spurios wake-ups 
     insertbuffer(value); 
     pthread_mutex_unlock(&buffer_mutex); 
     sem_post(&empty_sem); // post (increment) emptybuffer semaphore 
     //printf("Producer Thread %d adds %d added %d to buffer\n", pthread_self(), thread_numb, value); 
     printf("Producer Thread %d adds %d to the buffer, and the current buffer contains %d \n", pthread_self(), value, *buffer); 

    } 
    pthread_exit(0); 
} 

void *consumer2(void *thread_n) { 
    int thread_numb = *(int *)thread_n; 
    buffer_t value; 
    int i=0; 
    while (i++ < CONSUMER_LOOPS) { 
     pthread_mutex_lock(&buffer_mutex); 
     do { 
      pthread_mutex_unlock(&buffer_mutex); 
      sem_wait(&empty_sem); 
      pthread_mutex_lock(&buffer_mutex); 
     } while (isempty()); //check for spurios wakeups 
     value = dequeuebuffer(value); 
     pthread_mutex_unlock(&buffer_mutex); 
     sem_post(&full_sem); // post (increment) fullbuffer semaphore 
     printf("Consumer Thread %d dequeue %d from buffer, and the current buffer contains %d \n", pthread_self(), value, *buffer); 
    } 
    pthread_exit(0); 
} 

int main(int argc, int **argv) { 
    buffer_index = 0; 

    pthread_mutex_init(&buffer_mutex, NULL); 
    sem_init(&full_sem, // sem_t *sem 
      0, // int pshared. 0 = shared between threads of process, 1 = shared between processes 
      SIZE); // unsigned int value. Initial value 
    sem_init(&empty_sem, 
      0, 
      0); 
    /* full_sem is initialized to buffer size because SIZE number of 
     producers can add one element to buffer each. They will wait 
     semaphore each time, which will decrement semaphore value. 
     empty_sem is initialized to 0, because buffer starts empty and 
     consumer cannot take any element from it. They will have to wait 
     until producer posts to that semaphore (increments semaphore 
     value) */ 
    pthread_t thread[NUMB_THREADS]; 
    int thread_numb[NUMB_THREADS]; 
    int i; 
    for (i = 0; i < NUMB_THREADS;) { 
     thread_numb[i] = i; 
     if(i <= 2) 
     { 
      pthread_create(thread + i, // pthread_t *t 
         NULL, // const pthread_attr_t *attr 
         producer2, // void *(*start_routine) (void *) 
         thread_numb + i); // void *arg 

     } 
     thread_numb[i] = i; 
     // playing a bit with thread and thread_numb pointers... 
     pthread_create(&thread[i], // pthread_t *t 
         NULL, // const pthread_attr_t *attr 
         consumer2, // void *(*start_routine) (void *) 
         &thread_numb[i]); // void *arg 
     i++; 
    } 

    for (i = 0; i < NUMB_THREADS; i++) 
     pthread_join(thread[i], NULL); 

    pthread_mutex_destroy(&buffer_mutex); 
    sem_destroy(&full_sem); 
    sem_destroy(&empty_sem); 

    return 0; 
}  
+1

如果缓冲区包含要打印的可变数量的值,则需要在循环内执行一个“printf”。 – lurker

回答

0

无法打印未知长度的数组在同一行,但你可以改变你的insertbuffer显示每次插入值时的细节。或者,将打印作为单独的功能实施。然后称之为单线,显然。

void insertbuffer(int threadnum, buffer_t value) { 
    int i; 
    if (buffer_index < SIZE) { 
     buffer[buffer_index++] = value; 
     printf("Producer Thread %d adds %d to the buffer, and the current buffer contains", 
       threadnum, (int)value); 
     for(i=0; i<buffer_index; i++) { 
      if(i) 
       printf(","); 
      printf(" %d", (int)buffer[i]); 
     } 
     printf("\n"); 
    } else { 
     printf("Buffer overflow\n"); 
    } 
}