2015-03-19 42 views
0

試圖從我編碼的單獨文件中使用有界緩衝區,它似乎就是代碼變得瘋狂的地方。對C來說相當新穎,我想知道我是否正確使用緩衝區。實例化的概念不在這裏,所以如果我只是調用其中一個函數(如bbuff_blocking_insert),數組是否會被初始化?我如何進行適當的調用才能使其工作?C:使用單獨文件中的函數

candy.c

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <unistd.h> 
#include "bbuff.h" 
#include <stdbool.h> 
#include <time.h> 

_Bool stop_thread = false; 

typedef struct { 
    int source_thread; 
    double time_stamp_in_ms; 
} candy_t; 

double current_time_in_ms (void) { 
    struct timespec now; 
    clock_gettime(CLOCK_REALTIME, &now); 
    return now.tv_sec * 1000.0 + now.tv_nsec/1000000.0; 
} 

void* createCandy(void* arg) { 
    int r; 
    int factoryNumber = *(int*)arg; 
    while(!stop_thread) { 
     r = rand() % 4; 
     printf("Random Number: %d\n", r); 
     printf("\tFactory %d ship candy & wait %ds\n", factoryNumber, r); 
     candy_t *candy = (candy_t*)malloc(sizeof(candy_t)); 
     candy->source_thread = factoryNumber; 
     candy->time_stamp_in_ms = current_time_in_ms(); 
     bbuff_blocking_insert((void *)candy); 
     sleep(r); 
    } 
    printf("Candy-factory %d done\n", factoryNumber); 
    return 0; 
} 

void* extractCandy(void* arg) { 
    int r; 
    candy_t* candy; 
    while(true) { 
     candy = (candy_t*)bbuff_blocking_extract(); 
     printf("Candy Source Thread: %d\n", candy->source_thread); 
     r = rand() % 2; 
     sleep(r); 
    } 
    return 0; 
} 


int main(int argc, char* argv[]) { 
    //Extract Arguments 
    if (argc <= 1) { 
     printf("Insufficient Arguments\n"); 
     exit(-1); 
    } 
    int NO_FACTORIES = atoi(argv[1]); 
    int NO_KIDS = atoi(argv[2]); 
    int NO_SECONDS = atoi(argv[3]); 

    bbuff_init(); 

    //Spawn Factory Threads 
    pthread_t ftids[NO_FACTORIES]; 
    int factoryNumber[NO_FACTORIES]; 
    for (int i = 0; i < NO_FACTORIES; i++) { 
     factoryNumber[i] = i; 
     pthread_attr_t attr; 
     pthread_attr_init(&attr); 
     pthread_create(&ftids[i], &attr, createCandy, &factoryNumber[i]); 
    } 

    //Spawn Kid Threads 
    pthread_t ktids [NO_KIDS]; 
    for (int i = 0; i < NO_KIDS; i++) { 
     pthread_attr_t attr; 
     pthread_attr_init(&attr); 
     pthread_create(&ktids[i], &attr, extractCandy, NULL); 
    } 

    //Wait for Requested Time 
    for (int i = 0; i < NO_SECONDS; i++) { 
     sleep(1); 
     printf("Time %ds\n", i+1); 
    } 

    //Stop Factory Threads 
    stop_thread = true; 
    for (int i = 0; i < NO_FACTORIES; i++) { 
     pthread_join(ftids[i], NULL); 
    } 
    //Wait until no more candy 
    while(bbuff_is_data_available()) { 
     printf("Waiting for all candy to be consumed"); 
     sleep(1); 
    } 
    //Stop kid Threads 
    for (int i = 0; i < NO_KIDS; i++) { 
     pthread_cancel(ktids[i]); 
     pthread_join(ktids[i], NULL); 
    } 
    //Print Statistics 
    //Clean up any allocated memory 

    return 0; 
} 

bbuff.h

#ifndef BBUFF_H 
#define BBUFF_H 

#define QUEUE_SIZE 10 

void bbuff_init(void); 
void bbuff_blocking_insert(void* item); 
void* bbuff_blocking_extract(void); 
_Bool bbuff_is_data_available(void); 

#endif 

bbuff.c

#include "bbuff.h" 
pthread_mutex_t mutex; 
sem_t empty; 
sem_t full; 
int in = 0; 
int out = 0; 
int counter = 0; 
void* buffer[QUEUE_SIZE]; 

void bbuff_init(void){ 
    pthread_mutex_init(&mutex, NULL); 
    sem_init(&empty, 0, QUEUE_SIZE); 
    sem_init(&full, 0, 0); 
} 

void bbuff_blocking_insert(void* item) { 
    sem_wait(&empty); 
    pthread_mutex_lock(&mutex); 
    counter++; 
    buffer[in] = item; 
    in = (in+1) % QUEUE_SIZE; 
    pthread_mutex_unlock(&mutex); 
    sem_post(&full); 
} 

void* bbuff_blocking_extract(void) { 
    void* extractedItem; 
    sem_wait(&full); 
    pthread_mutex_lock(&mutex); 
    counter--; 
    extractedItem = buffer[out]; 
    buffer[out] = NULL; 
    out = out % QUEUE_SIZE; 
    pthread_mutex_unlock(&mutex); 
    sem_post(&empty); 
    return extractedItem; 
} 

輸出

$ ./candykids 1 1 10 
Random Number: 3 
    Factory 0 ship candy & wait 3s 
Candy Source Thread: 0 
Time 1s 
Time 2s 
Random Number: 1 
    Factory 0 ship candy & wait 1s 
Time 3s 
Segmentation fault (core dumped) 
+1

請定義去瘋狂。不編譯?段錯誤?內核恐慌? – merlin2011 2015-03-19 07:05:24

+0

@ merlin2011它運行正常,但我幾乎肯定該項目沒有被放置在緩衝區中。 – Aaron 2015-03-19 07:06:56

+0

請添加您所需的輸出和觀察輸出。 – merlin2011 2015-03-19 07:08:40

回答

1

bbuff_blocking_extract()

out = out % QUEUE_SIZE; 

應該是:

out = (out+1) % QUEUE_SIZE; 
+0

耶穌小錯,謝謝。 – Aaron 2015-03-19 07:45:25

+0

從所有OP的代碼中挑出一個錯誤並非易事。 – merlin2011 2015-03-19 08:53:44

相關問題