C 语言中实现环形缓冲区

2025-05-27 0 58

1.实现代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107
#include

#include

#include

#include

#include

#define BUFFSIZE 1024 * 1024

#define min(x, y) ((x) < (y) ? (x) : (y))

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

struct cycle_buffer {

unsigned char *buf;

unsigned int size;

unsigned int in;

unsigned int out;

pthread_mutex_t lock;

};

static struct cycle_buffer *fifo = NULL;

static int init_cycle_buffer(void)

{

int size = BUFFSIZE, ret;

ret = size & (size - 1);

if (ret)

return ret;

fifo = (struct cycle_buffer *) malloc(sizeof(struct cycle_buffer));

if (!fifo)

return -1;

memset(fifo, 0, sizeof(struct cycle_buffer));

fifo->size = size;

fifo->in = fifo->out = 0;

pthread_mutex_init(&fifo->lock, NULL);

fifo->buf = (unsigned char *) malloc(size);

if (!fifo->buf)

free(fifo);

else

memset(fifo->buf, 0, size);

return 0;

}

unsigned int fifo_get(unsigned char *buf, unsigned int len)

{

unsigned int l;

len = min(len, fifo->in - fifo->out);

l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));

memcpy(buf, fifo->buf + (fifo->out & (fifo->size - 1)), l);

memcpy(buf + l, fifo->buf, len - l);

fifo->out += len;

return len;

}

unsigned int fifo_put(unsigned char *buf, unsigned int len)

{

unsigned int l;

len = min(len, fifo->size - fifo->in + fifo->out);

l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));

memcpy(fifo->buf + (fifo->in & (fifo->size - 1)), buf, l);

memcpy(fifo->buf, buf + l, len - l);

fifo->in += len;

return len;

}

static void * thread_read(void *arg)

{

char buf[1024];

unsigned int n;

pthread_detach(pthread_self());

for (;;) {

memset(buf, 0, sizeof(buf));

pthread_mutex_lock(&fifo->lock);

n = fifo_get(buf, sizeof(buf));

pthread_mutex_unlock(&fifo->lock);

write(STDOUT_FILENO, buf, n);

}

printf("nnafter thread_read : %snn",buf);

return NULL;

}

static void * thread_write(void *arg)

{

unsigned char buf[] = "hello world";

pthread_detach(pthread_self());

for (;;) {

pthread_mutex_lock(&fifo->lock);

fifo_put(buf, strlen(buf));

pthread_mutex_unlock(&fifo->lock);

}

return NULL;

}

int main(void)

{

int ret;

pthread_t wtid, rtid;

ret = init_cycle_buffer();

if (ret == -1)

return ret;

pthread_create(&wtid, NULL, thread_write, NULL);

pthread_create(&rtid, NULL, thread_read, NULL);

pthread_exit(NULL);

return 0;

}

1.buffer指向存放数据的缓冲区,size是缓冲区的大小,in是写指针下标,out是读指针下标,在len和(fifo->size – fifo->in + fifo->out)之间取一个较小的值赋给len。注意,当(fifo->in == fifo->out+fifo->size)时,表示缓冲区已满,此时得到的较小值一定是0,后面实际写入的字节数也全为0。另一种边界情况是当len很大时(因为len是无符号的,负数对它来说也是一个很大的正数),这一句也能保证len取到一个较小的值,因为fifo->in总是大于等于fifo->out,所以后面的那个表达式的值不会超过fifo->size的大小把上一步决定的要写入的字节数len“切开”,这里又使用了一个技巧。注意:实际分配给fifo->buffer的字节数fifo->size,必须是2的幂,否则这里就会出错。既然fifo->size是2的幂,那么 (fifo->size-1)也就是一个后面几位全为1的数,也就能保证(fifo->in & (fifo->size – 1))总为不超过(fifo->size – 1)的那一部分,和(fifo->in)% (fifo->size – 1)的效果一样。

2.这样后面的代码就不难理解了,它先向fifo->in到缓冲区末端这一块写数据,如果还没写完,在从缓冲区头开始写入剩下的,从而实现了循环缓冲。最后,把写指针后移len个字节,并返回len。

3.从上面可以看出,fifo->in的值可以从0变化到超过fifo->size的数值,fifo->out也如此,但它们的差不会超过fifo->size 。

以上就是环形缓冲区域的C语言实现详解,希望对大家有所帮助,谢谢支持!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C 语言中实现环形缓冲区 https://www.kuaiidc.com/74864.html

相关文章

发表评论
暂无评论