gpt4 book ai didi

c - 具有循环缓冲区的多生产者单消费者

转载 作者:行者123 更新时间:2023-11-30 17:57:00 25 4
gpt4 key购买 nike

需要帮助才能实现以下功能。

我有多个生产者线程(每个线程写入 100 字节数据)到环缓冲区。一个读取器(消费者)线程一次读取 100 个字节并写入 stdout。(最后我想根据数据写入文件)

通过这个实现,我有时会从环形缓冲区读取数据错误。见下文由于环形缓冲区大小很小,它会变满并且部分数据丢失。这不是我当前的问题。

** Questions:

  1. 在打印从ringbuffer读取的数据时,一些数据得到互换了!!我找不到错误。
  2. 逻辑/方法正确吗? (或)是否有更好的方法来做到这一点

ringbuffer.h

#define RING_BUFFER_SIZE  500
struct ringbuffer
{
char *buffer;
int wr_pointer;
int rd_pointer;
int size;
int fill_count;
};

ringbuffer.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ringbuffer.h"

int init_ringbuffer(char *rbuffer, struct ringbuffer *rb, size_t size)
{
rb->buffer = rbuffer;
rb->size = size;
rb->rd_pointer = 0;
rb->wr_pointer = 0;
rb->fill_count = 0;
return 0;
}

int rb_get_free_space (struct ringbuffer *rb)
{
return (rb->size - rb->fill_count);
}

int rb_write (struct ringbuffer *rb, unsigned char * buf, int len)
{
int availableSpace;
int i;

availableSpace = rb_get_free_space(rb);
printf("In Write AVAIL SPC=%d\n",availableSpace);
/* Check if Ring Buffer is FULL */
if(len > availableSpace)
{
printf("NO SPACE TO WRITE - RETURN\n");
return -1;
}

i = rb->wr_pointer;
if(i == rb->size) //At the end of Buffer
{
i = 0;
}
else if (i + len > rb->size)
{
memcpy(rb->buffer + i, buf, rb->size - i);
buf += rb->size - i;
len = len - (rb->size - i);
rb->fill_count += len;
i = 0;
}
memcpy(rb->buffer + i, buf, len);
rb->wr_pointer = i + len;
rb->fill_count += len;

printf("w...rb->write=%tx\n", rb->wr_pointer );
printf("w...rb->read=%tx\n", rb->rd_pointer );
printf("w...rb->fill_count=%d\n", rb->fill_count );
return 0;
}

int rb_read (struct ringbuffer *rb, unsigned char * buf, int max)
{
int i;

printf("In Read,Current DATA size in RB=%d\n",rb->fill_count);
/* Check if Ring Buffer is EMPTY */
if(max > rb->fill_count)
{
printf("In Read, RB EMPTY - RETURN\n");
return -1;
}

i = rb->rd_pointer;
if (i == rb->size)
{
i = 0;
}
else if(i + max > rb->size)
{
memcpy(buf, rb->buffer + i, rb->size - i);
buf += rb->size - i;
max = max - (rb->size - i);
rb->fill_count -= max;
i = 0;
}
memcpy(buf, rb->buffer + i, max);
rb->rd_pointer = i + max;
rb->fill_count -= max;

printf("r...rb->write=%tx\n", rb->wr_pointer );
printf("r...rb->read=%tx\n", rb->rd_pointer );
printf("DATA READ ---> %s\n",(char *)buf);
printf("r...rb->fill_count=%d\n", rb->fill_count );
return 0;
}

最佳答案

在生产者处,您还需要等待有空空间条件的条件变量。这两个条件变量都应该无条件地发出信号,即当消费者从环形缓冲区中删除一个元素时,它应该向生产者发出信号;当生产者将某些东西放入缓冲区时,它应该向消费者发出信号。另外,我会将这个等待/信号逻辑移至 rb_read 和 rb_write 实现中,因此您的环形缓冲区对于程序的其余部分来说是一个“完整的使用解决方案”。

关于c - 具有循环缓冲区的多生产者单消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13069970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com