2016-07-06 63 views
0

針對某個類正在處理生產者和消費者問題,並且無法進行最後的修改。我遇到的問題是,我認爲我的互斥鎖並沒有鎖定我的線程功能。例如,如果我運行該程序並將其傳遞給參數2 4 4 7,它將打印8 7,然後2秒鐘後它將打印8 8和8 9,等等。我嘗試過使用trylock並在信號量周圍移動,但無濟於事。有沒有什麼東西是我失蹤的時候,導致沒有線程被鎖定?無法獲取互斥鎖來防止線程訪問某個函數

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 
typedef int buffer_item; 
#define BUFFER_SIZE 5 
#define TRUE 1 


buffer_item START_NUMBER; 
int counter; 
int insert_item(buffer_item item); 
int remove_item(buffer_item *item); 
buffer_item buffer[BUFFER_SIZE]; 
void* producer(void *ptr); 
void* consumer(void *ptr); 
pthread_cond_t condc, condp; 
pthread_mutex_t mutex; 
int sleepTime, producerThreads, consumerThreads,a; 
pthread_attr_t attr; 
sem_t full, empty; 

int insert_item(buffer_item item) 
{ 
    if(counter < BUFFER_SIZE) { 
     buffer[counter] = item; 
     counter++; 
     return 0; 
    } 
    else { 
     return -1; 
    } 
} 
int remove_item(buffer_item *item) 
{ 
    if(counter > 0) { 
     *item = buffer[(counter-1)]; 
     counter--; 
     return 0; 
    } 
    else { 
     return -1; 
    } 
} 

void* producer(void *ptr) { 
    buffer_item item; 
    item = START_NUMBER; 
    while(TRUE) { 
     sleep(sleepTime);  
     sem_wait(&empty); 
     pthread_mutex_lock(&mutex);  
     if(insert_item(item)) { 
     fprintf(stderr, "error \n"); 
     } 
     else { 
     printf("producer%u produced %d\n", (unsigned int)pthread_self(),item); 
     item++; 
     }  
     pthread_mutex_unlock(&mutex); 
     sem_post(&full); 
    } 
     } 
void* consumer(void *ptr) { 
    buffer_item item; 
    while(TRUE) { 
     sleep(sleepTime); 
     sem_wait(&full); 
     pthread_mutex_lock(&mutex); 
     if(remove_item(&item)) { 
     fprintf(stderr, "error \n"); 
     } 
     else { 
     printf("consumer%u consumed %d\n", (unsigned int)pthread_self(),item); 
     } 
     pthread_mutex_unlock(&mutex); 
     sem_post(&empty); 

    } 
} 
void initializeData() { 
    pthread_mutex_init(&mutex, NULL); 
    sem_init(&full, 0, 0); 
    sem_init(&empty, 0, BUFFER_SIZE); 
    pthread_attr_init(&attr); 
    counter = 0; 
} 

int main(int argc, char **argv) { 

    sleepTime = atoi(argv[1]); 
    producerThreads = atoi(argv[2]); 
    consumerThreads = atoi(argv[3]); 
    START_NUMBER = atoi(argv[4]); 
    initializeData(); 
    pthread_t pro, con; 


    pthread_mutex_init(&mutex, NULL); 
    pthread_cond_init(&condc, NULL); 
    pthread_cond_init(&condp, NULL); 

    for(a=0; a< consumerThreads;a++) 
    pthread_create(&con, NULL, consumer, NULL); 
    for(a=0;a<producerThreads;a++) 
    pthread_create(&pro, NULL, producer, NULL); 


    pthread_join(con, NULL); 
    pthread_join(pro, NULL); 


    pthread_mutex_destroy(&mutex); 
    pthread_cond_destroy(&condc); 
    pthread_cond_destroy(&condp); 
    sleep(sleepTime); 

} 
+0

你期待什麼輸出? – Dmitri

+0

啊我的錯誤,預期的輸出是數字遞增,從一開始 生產者12323112採取在4參數開始生產了7 製片12312310生產的8 消費者1321312消耗7 製片人...... 9 消費者.. ...消耗8' – nojames

+0

因爲每個(生產者)線程都以自己的'item'變量開始,初始化爲'START_NUMBER'。因爲他們每個人都使用和增加他們自己的本地副本,所以每個編號都會得到與生產者相同數量的副本,每個副本顯示兩次,一次產生一次,一次消耗 - 四次生產者線程八次。 – Dmitri

回答

1

感謝您的幫助德米特里,圍繞線移動後,你告訴我,並與我的一個朋友的一些討論,我終於得到了它的開始輸出正確的數字!

This is the output i have been looking for

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 
typedef int buffer_item; 
#define BUFFER_SIZE 5 
#define TRUE 1 


buffer_item START_NUMBER; 
buffer_item item; 
int counter; 
int insert_item(buffer_item item); 
int remove_item(buffer_item *item); 
buffer_item buffer[BUFFER_SIZE]; 
void* producer(void *ptr); 
void* consumer(void *ptr); 
pthread_cond_t condc, condp; 
pthread_mutex_t mutex; 
int sleepTime, producerThreads, consumerThreads, a, item; 
pthread_attr_t attr; 
sem_t full, empty; 

int insert_item(buffer_item item) 
{ 
    if(counter < BUFFER_SIZE) { 
     buffer[counter] = item; 
     counter++; 
     return 0; 
    } 
    else { 
     return -1; 
    } 
} 
int remove_item(buffer_item *item) 
{ 
    if(counter > 0) { 
     *item = buffer[(counter-1)]; 
     printf("consumer%u consumed %d\n", (unsigned int)pthread_self(),buffer[counter-1]); 
     counter--; 
     return 0; 
    } 
    else { 
     return -1; 
    } 
} 

void* producer(void *ptr) {  
    while(TRUE) { 
     sleep(sleepTime);  
     sem_wait(&empty); 
     pthread_mutex_lock(&mutex);  
     if(insert_item(START_NUMBER)) { 
     fprintf(stderr, "error \n"); 
     } 
     else { 
     printf("producer%u produced %d\n", (unsigned int)pthread_self(),START_NUMBER); 
     START_NUMBER++; 
     }  
     pthread_mutex_unlock(&mutex); 
     sem_post(&full); 
    } 
} 

void* consumer(void *ptr) { 
    while(TRUE) { 
     sleep(sleepTime); 
     sem_wait(&full); 
     pthread_mutex_lock(&mutex); 
     if(remove_item(&item)) { 
     fprintf(stderr, "error \n"); 
     } 
     else { 
     // printf("consumer%u consumed %d\n", (unsigned int)pthread_self(),&START_NUMBER); 
     } 
     pthread_mutex_unlock(&mutex); 
     sem_post(&empty); 

    } 
} 
void initializeData() { 
    pthread_mutex_init(&mutex, NULL); 
    sem_init(&full, 0, 0); 
    sem_init(&empty, 0, BUFFER_SIZE); 
    pthread_attr_init(&attr); 
    counter = 0; 
} 

int main(int argc, char **argv) { 

    sleepTime = atoi(argv[1]); 
    producerThreads = atoi(argv[2]); 
    consumerThreads = atoi(argv[3]); 
    START_NUMBER = atoi(argv[4]); 
    item = START_NUMBER; 
    initializeData(); 
    pthread_t pro, con; 


    pthread_mutex_init(&mutex, NULL); 
    pthread_cond_init(&condc, NULL); 
    pthread_cond_init(&condp, NULL); 

    for(a=0; a< consumerThreads;a++) 
    pthread_create(&con, NULL, consumer, NULL); 
    for(a=0;a<producerThreads;a++) 
    pthread_create(&pro, NULL, producer, NULL); 


    pthread_join(con, NULL); 
    pthread_join(pro, NULL); 


    pthread_mutex_destroy(&mutex); 
    pthread_cond_destroy(&condc); 
    pthread_cond_destroy(&condp); 
    sleep(sleepTime); 

}