2011-09-17 257 views
-1

可能有人检查我的代码,并告诉我,如果我在正确的轨道上。它好像我有点失去了..如果你看到我的错误,请让我知道他们..生产者/消费者

我想要做的是使用我自己的信号量和GCD解决有界缓冲区。

在此先感谢..

sema.c

void procure(Semaphore *semaphore) { 

     pthread_mutex_lock(semaphore->mutex1); 

     while(semaphore->value <= 0) 
       pthread_cond_wait(&semaphore->condition, semaphore->mutex1); 


     semaphore->value--; 

     pthread_mutex_unlock(semaphore->mutex1); 


} 

void vacate(Semaphore *semaphore) { 

     pthread_mutex_lock(semaphore->mutex1); 
     semaphore->value++; 
     pthread_cond_signal(&semaphore->condition); 
     pthread_mutex_unlock(semaphore->mutex1);   
} 


void init (Semaphore *semaphore){ 

     semaphore->value = 1; 

     pthread_mutex_t myMutex; 
     semaphore->mutex1 = &myMutex; 
     pthread_mutex_init(semaphore->mutex1, NULL); 



} 

void destroy (Semaphore *semaphore) { 

     pthread_mutex_destroy(semaphore->mutex1); 


} 

和main.c中

struct variables { 

     Semaphore *sem; 

}; 

struct variables vars; 

void constructer (int *buffer, int *in, int *out) { 

     init(vars.sem); 

} 


void deconstructer() { 

     destroy(vars.sem); 

} 



int rand_num_gen() { 
     uint_fast16_t buffer; 
     int file; 
     int *rand; 

     file = open("/dev/random", O_RDONLY); 


     while(1) { 

       read(file, &buffer, sizeof(buffer)); 

       printf("16 bit number: %hu\n", buffer); 

       *rand = (int) buffer; 

       close(file); 


       break; 
     } 

     return *rand; 
} 


void put_buffer(int* buffer, int* in, int* out) { 

     buffer[*in] = rand_num_gen(); // produce 

     procure(vars.sem);    // wait here 
       *in = (*in + 1) % BUF_SIZE; 
     vacate(vars.sem); 

} 

void get_buffer(int* buffer, int* in, int* out) { 

     int value; 

     procure(vars.sem); 
       value = buffer[*out]; 
     vacate(vars.sem); 

     *out = (*out + 1) % BUF_SIZE; 

} 

int main (void) { 


     int *in, *out, *buffer;  

     constructer(buffer, in, out);   



     dispatch_queue_t producer, consumer;  

     producer = dispatch_queue_create("put_buffer", NULL); 
     consumer = dispatch_queue_create("get_buffer", NULL); 



     dispatch_async(producer, 
         ^{ 
           int i; 
           do 
           { 
             put_buffer(buffer, in, out); 


             dispatch_async(consumer, 
                 ^{ 
                   get_buffer(buffer, in, out); 

                   if (i == RUN_LENGTH) exit(EXIT_SUCCESS); 
                 }); 
           } 
           while (i < RUN_LENGTH);    
         }); 

     dispatch_main();     

     deconstructer(); 

     exit (0); 
} 
+0

我在这里收到坏访问'buffer [* in] = rand_num_gen();'我该如何解决它? – canaan

+1

这是哪种语言? C没有lambda('^')运算符。 –

回答

2

你的代码有缺陷。在init函数中,您将本地变量的地址分配给semaphore->mutex1,并且函数返回时,此地址将无效。后来你仍然使用这个地址,所以这导致未定义的行为

必须要么分配用于直接在信号量(没有指针)互斥存储器或经由malloc分配内存。

更新:

你的程序有这么多的错误,你一定要挑一个更简单的主题,以了解内存管理的基本概念,如何分配,使用和引用缓冲,做正确的错误处理,等等。这是你的代码的一个稍微编辑的版本。它仍然行不通,但可能有一些你应该遵循的想法。

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

void procure(Semaphore *semaphore) { 
    pthread_mutex_lock(semaphore->mutex1); 

    while (semaphore->value <= 0) 
    pthread_cond_wait(&semaphore->condition, semaphore->mutex1); 

    semaphore->value--; 
    pthread_mutex_unlock(semaphore->mutex1); 
} 

void vacate(Semaphore *semaphore) { 
    pthread_mutex_lock(semaphore->mutex1); 
    semaphore->value++; 
    pthread_cond_signal(&semaphore->condition); 
    pthread_mutex_unlock(semaphore->mutex1); 
} 

struct variables { 
    mutex_t sem_mutex; 
    Semaphore sem; 
}; 

struct variables vars; 

void constructor(int *buffer, int *in, int *out) { 
    vars.sem.value = 1; 
    vars.sem.mutex1 = &vars.sem_mutex; 
    pthread_mutex_init(vars.sem.mutex1, NULL); 
} 

void deconstructor() { 
    pthread_mutex_destroy(&semaphore->mutex1); 
} 

int rand_num_gen() { 
    const char *randomfile = "/dev/random"; 
    unsigned char buffer[2]; // Changed: always treat files as byte sequences. 
    FILE *f = fopen(randomfile, "rb"); 
    // Changed: using stdio instead of raw POSIX file access, 
    // since the API is much simpler; you don't have to care 
    // about interrupting signals or partial reads. 

    if (f == NULL) { // Added: error handling 
    fprintf(stderr, "E: cannot open %s\n", randomfile); 
    exit(EXIT_FAILURE); 
    } 
    if (fread(buffer, 1, 2, f) != 2) { // Added: error handling 
    fprintf(stderr, "E: cannot read from %s\n", randomfile); 
    exit(EXIT_FAILURE); 
    } 
    fclose(f); 
    int number = (buffer[0] << CHAR_BIT) | buffer[1]; 
    // Changed: be independent of the endianness of the system. 
    // This doesn't matter for random number generators but is 
    // still an important coding style. 
    printf("DEBUG: random number: %x\n", (unsigned int) number); 
    return number; 
} 

void put_buffer(int* buffer, int* in, int* out) { 
    buffer[*in] = rand_num_gen(); // produce 
    procure(&vars.sem); // wait here 
    *in = (*in + 1) % BUF_SIZE; 
    vacate(&vars.sem); 
} 

void get_buffer(int* buffer, int* in, int* out) { 
    int value; 
    procure(&vars.sem); 
    value = buffer[*out]; 
    vacate(&vars.sem); 
    *out = (*out + 1) % BUF_SIZE; 
} 

int main (void) { 
    int inindex = 0, outindex = 0; 
    int buffer[BUF_SIZE]; 

    constructor(buffer, &inindex, &outindex); 
    // Changed: provided an actual buffer and actual variables 
    // for the indices into the buffer. 
    dispatch_queue_t producer, consumer;  
    producer = dispatch_queue_create("put_buffer", NULL); 
    consumer = dispatch_queue_create("get_buffer", NULL); 

    dispatch_async(producer, ^{ 
    int i; 
    do { 
     put_buffer(buffer, &inindex, &outindex); 
     dispatch_async(consumer, ^{ 
     get_buffer(buffer, &inindex, &outindex); 
     if (i == RUN_LENGTH) exit(EXIT_SUCCESS); 
     }); 
    } while (i < RUN_LENGTH); 
    }); 

    dispatch_main();  
    deconstructor(); 
    exit (0); 
} 

正如我所说的,我没有抓住所有的错误。

+0

这么多的错误,我有..感谢您指出了一个出... – canaan

+0

我不是调用建筑工和deconstructer功能..我固定的,但不可能看到 – canaan

+0

你永远不会初始化'in'变量的任何差异。我认为你想要声明'in'和'out'为int in = 0,out = 0;并将它们的地址传递给你的函数。 – nos