我很难使用多个文件进行结构化工作.请帮忙?

Par*_*dox 1 c unix pthreads header-files

我正在尝试解决消费者/生产者问题,我必须创建三个不同的类.

主类包括线程的创建和消费者/生产者逻辑

另外两个类是

  • 环形缓冲区的头文件
  • 包含环形缓冲区实现的文件

我在尝试编译时遇到以下错误:

ringbuf.c: In function ‘rb_init’:
ringbuf.c:10: warning: incompatible implicit declaration of built-in function ‘malloc’
ringbuf.c:10: error: invalid application of ‘sizeof’ to incomplete type ‘struct ringbuf_t’ 
ringbuf.c:12: error: dereferencing pointer to incomplete type
Run Code Online (Sandbox Code Playgroud)

我还有很多其他的错误,但是一旦我完成这个错误,我就可以自己处理.

这是缓冲区的头文件:

struct ringbuf_t 
{
    pthread_mutex_t mutex; /* lock to protect from simutaneous access to the buffer */
    pthread_cond_t cond_full; /* producer needs to wait when the buffer is full */
    pthread_cond_t cond_empty; /* consumer needs to wait when the buffer is empty */
    int bufsiz; /* size of the buffer; you may use an empty slot to differentiate the situation the buffer is full or empty */
    int front; /* index of the first element */
    int back; /* index next to the last element (or index to the first empty slot) */
    int count; //keeps track of the number of elements in the buffer
    char* buf; /* buffer itself */
};

/* return the pointer to the newl created and initialized ring buffer of the given size */
extern struct ringbuf_t* rb_init(int bufsiz);

/* reclaim the ring buffer */
extern void rb_finalize(struct ringbuf_t* rb);

/* return the current number of elements in the buffer */
extern int rb_size(struct ringbuf_t* rb);

/* return non-zero (true) if the buffer is currently full */
extern int rb_is_full(struct ringbuf_t* rb);

/* return non-zero (true) if the buffer is currently empty */
extern int rb_is_empty(struct ringbuf_t* rb);

/* insert (i.e., append) a character into the buffer; if the buffer is full, the caller thread will be blocked */
extern void rb_insert(struct ringbuf_t* rb, int c);

/* retrieve a character at the front of the ring buffer; if the buffer is empty, the caller thread will be blocked */
extern int rb_remove(struct ringbuf_t* rb);
Run Code Online (Sandbox Code Playgroud)

这是缓冲区的实现:

#include <malloc.h>
#include <stdio.h>

struct ringbuf_t 
{
    pthread_mutex_t mutex; /* lock to protect from simutaneous access to the buffer */
    pthread_cond_t cond_full; /* producer needs to wait when the buffer is full */
    pthread_cond_t cond_empty; /* consumer needs to wait when the buffer is empty */
    int bufsiz; /* size of the buffer; you may use an empty slot to differentiate the situation the buffer is full or empty */
    int front; /* index of the first element */
    int back; /* index next to the last element (or index to the first empty slot) */
    int count; //keeps track of the number of elements in the buffer
    char* buf; /* buffer itself */
};


struct ringbuf_t* rb_init(int bufsiz)
{
    struct ringbuf_t* buffer = (struct ringbuf_t*)malloc(sizeof(struct ringbuf_t));

    buffer->bufsiz = bufsiz;
    buffer->front = 0;
    buffer->back = 0;
    buffer->count = 0;
}


/* reclaim the ring buffer */
void rb_finalize(struct ringbuf_t* rb)
{
    free(rb);
    pthread_mutex_destroy(&rb->mutex);
    printf("\nnotice - ring buffer finalized");
}



/* return the current number of elements in the buffer */
int rb_size(struct ringbuf_t* rb)
{
    return (rb->count);
}



/* return non-zero (true) if the buffer is currently full */
int rb_is_full(struct ringbuf_t* rb)
{
    return ((rb->count) == rb->bufsiz);
}



/* return non-zero (true) if the buffer is currently empty */
int rb_is_empty(struct ringbuf_t* rb)
{
    return ((rb->count) == 0);
}



/* insert (i.e., append) a character into the buffer; if the buffer is full, the caller thread will be blocked */
void rb_insert(struct ringbuf_t* rb, int c)
{
    char* temp;


    if(rb->count < rb->bufsiz)
    {
        if(rb->count == 0)
        {
            rb->front = 0;
            rb->back = 0;
            rb->buf = c;
            rb->count++;
        }
        else
        {
            if(rb->front < (rb->bufsiz - 1))
            {
                temp = rb->buf;
                temp = temp + rb->front + 1;
                temp = c;
                rb->front++;
            }
            else if(rb->front == (rb->bufsiz -1))
            {
                rb->front = 0;
                rb->buf = c;
            }
        }
    }
    else
    {
        printf("\nerror - trying to insert into full buffer");
    }
}



/* retrieve a character at the tail (back) of the ring buffer; if the buffer is empty, the caller thread will be blocked */
int rb_remove(struct ringbuf_t* rb)
{
    if(rb->count != 0)
    {
        count--;
        if(rb->back < (rb->bufsiz-1)
        {
            rb->back++;
        }
        else if(rb->back == (rb->bufsiz -1))
        {
            rb->back = 0;
        }
    }
    else
    {
        printf("\nerror - trying to remove from empty buffer");
    }

}
Run Code Online (Sandbox Code Playgroud)

这是主要类:

#include <stdio.h>
#include <pthread.h>
#include <ringbuf.h>


    //creating a static ring buffer
struct ringbuf* mybuffer = rb_init(10);

int thisChar;

    /*
     consumer thread, reads one character at a time, sets the lock when addinga character to the ring buffer
     while locked it checks if the buffer is full, waits for a slot, and then continues.
     */
void* consumer(void* arg)
{
    printf("consumer started");

    while(thisChar != EOF)
    {
        pthread_mutex_lock(&(mybuffer->mutex));

        while(rb_is_empty(mybuffer))
            pthread_cond_wait(&(mybuffer->cond_full), &(mybuffer->mutex));

        printf("%s", (char)rb_remove(mybuffer));

        pthread_cond_signal(&(mybuffer->cond_empty));

        pthread_mutex_unlock(&(mybuffer->mutex));
    }
}

    /*
     producer thread, takes one character at a time from the buffer, (while the buffer is not empty)
     and prints it to the screen.
     */


void* producer(void* arg)
{
    printf("producer started");

    while ((thisChar = getchar()) != EOF)
    {

        pthread_mutex_lock(&(mybuffer->mutex));

        while(rb_is_full(mybuffer))
            pthread_cond_wait(&(mybuffer->cond_empty), &(mybuffer->mutex));

        rb_insert(mybuffer, thisChar);

        pthread_cond_signal(&(mybuffer->cond_full));

        pthread_mutex_unlock(&(mybuffer->mutex));
    }
}


int main()
{

        //declaring threads
    pthread_t t0, t1;


        //creating threads as condumer, producer
    p_thread_create(&t0, NULL, consumer, (void*)mybuffer);
    p_thread_create(&t1, NULL, producer, (void*)mybuffer);


    pthread_join(t0, NULL);
    pthread_join(t1, NULL);

    rb_finalize(mybuffer);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我错过了一些东西,但我需要首先完成这个!请帮忙!

sar*_*old 6

用你的#include <malloc.h>线替换#include <stdlib.h>.这将修复你在这里粘贴的错误(可能还有很多).执行此操作后,请返回代码并删除调用中的所有强制转换malloc(3):

struct ringbuf_t* buffer = (struct ringbuf_t*)malloc(sizeof(struct ringbuf_t));
Run Code Online (Sandbox Code Playgroud)

(struct ringbuf_t*)自从大约1989年将函数原型推入语言以来,这是不必要的.

  • @sarnold,我认为你的编译器会告诉你:)你不应该首先在C++中使用`malloc`.本质上,这告诉您C和C++是类似的语言,可以使声明兼容(对于头文件)但具有不兼容性,使得几乎不可能使用为其中一个编写的干净代码供另一个使用. (2认同)