2016-02-27 256 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"); 
    } 
}