gpt4 book ai didi

具有阻塞读取和非阻塞写入的循环/环形缓冲区?

转载 作者:太空宇宙 更新时间:2023-11-04 05:42:32 26 4
gpt4 key购买 nike

我正在用户空间中搜索 C 语言的环形缓冲区实现,因此我可以在我的库中使用它。

因为我需要一个环形缓冲区

  • 非阻塞写入(=覆盖最旧的数据)
  • 如果为空则阻止读取

我搜索了一会儿,记得我曾使用 wait_event_interruptiblewake_up_interruptible 在内核模式下做这样的事情。

但是在用户空间中使用了什么,所以我也许可以结合该方法搜索环形缓冲区?我不想重新发明轮子 - 周围有很多环形缓冲区解决方案。

在此先致谢并致以亲切的问候!

编辑:

似乎 pthread_cond_wait 可能等同于 wait_event_interruptible

最佳答案

用一些代码添加另一个答案,这与我的另一个答案中的 pseudocde 不是 1:1 匹配。将此标记为 wiki 答案,以防有人想要添加评论或进行其他改进。非常简单的ringbuffer的C phtread mutex+condition variable实现:

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

#define RINGBUFFER_SIZE (5)
int ringbuffer[RINGBUFFER_SIZE];
unsigned reader_unread = 0;
unsigned writer_next = 0;
pthread_mutex_t ringbuffer_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ringbuffer_written_cond = PTHREAD_COND_INITIALIZER;

void process_code(int ch) {
int counter;
printf("Processing code %d", ch);
for(counter=5; counter>0; --counter) {
putchar('.');
fflush(stdout);
sleep(1);
}
printf("done.\n");

}

void *reader() {
pthread_mutex_lock(&ringbuffer_mutex);
for(;;) {
if (reader_unread == 0) {
pthread_cond_wait(&ringbuffer_written_cond, &ringbuffer_mutex);
}
if (reader_unread > 0) {

int ch;
int pos = writer_next - reader_unread;
if (pos < 0) pos += RINGBUFFER_SIZE;
ch = ringbuffer[pos];
--reader_unread;

if (ch == EOF) break;

pthread_mutex_unlock(&ringbuffer_mutex);
process_code(ch);
pthread_mutex_lock(&ringbuffer_mutex);
}
}
pthread_mutex_unlock(&ringbuffer_mutex);

puts("READER THREAD GOT EOF");
return NULL;
}

void *writer() {
int ch;
do {
int overflow = 0;
ch = getchar();

pthread_mutex_lock(&ringbuffer_mutex);

ringbuffer[writer_next] = ch;

++writer_next;
if (writer_next == RINGBUFFER_SIZE) writer_next = 0;

if (reader_unread < RINGBUFFER_SIZE) ++reader_unread;
else overflow = 1;

pthread_cond_signal(&ringbuffer_written_cond);
pthread_mutex_unlock(&ringbuffer_mutex);

if (overflow) puts("WARNING: OVERFLOW!");

} while(ch != EOF);

puts("WRITER THREAD GOT EOF");
return NULL;
}

int main(void)
{
pthread_t reader_thread, writer_thread;

puts("Starting threads. Type text and press enter, or type ctrl-d at empty line to quit.");
pthread_create(&reader_thread, NULL, reader, NULL);
pthread_create(&writer_thread, NULL, writer, NULL);

pthread_join(writer_thread, NULL);
pthread_join(reader_thread, NULL);

return 0;
}

关于具有阻塞读取和非阻塞写入的循环/环形缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14703707/

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