8000 添加生产者消费者原型,当然也不能保证满足各种测试条件,添加需要解决问题Readme.md · home-coder/ring-buffer@572b56a · GitHub
[go: up one dir, main page]

Skip to content

Commit 572b56a

Browse files
committed
添加生产者消费者原型,当然也不能保证满足各种测试条件,添加需要解决问题Readme.md
1 parent fe645a1 commit 572b56a

File tree

5 files changed

+166
-8
lines changed

5 files changed

+166
-8
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ http://www.cnblogs.com/Anker/p/3481373.html
1717
2.内核数据写入,与mmap后的用户空间取走这个buffer的数据如何同步
1818
3.内核模块的地址如何在用户空间操作
1919

20-
针对上面的问题,如下思考
20+
针对上面的问题,如下思考
2121
经过x86测试,得知写入数据大于ringbuffer给出的最大尺寸4096后,剩余的数据虽然走kfifo_put方法,但是数据并没有写入或者覆盖掉起始处的buffer,导致数据丢失,
2222
所有后续 需要针对这个问题进行判断:如果缓冲区满了就等待,当读者将数据取走腾出空间了,写者再写入。这样写线程可以让出cpu,让他在这个等待间隙做其它的事情。
2323
当然我的测试方法是写者很快,而读者很慢的情景
24+
25+
26+
测试:
27+
需要针对helper中的生产者消费者 模型熟练掌握以后,在将kfifo的项目代码改编成包含这种模式的,目的是解决上面的问题 《针对上面的问题,如下思考》。

helper/linux/Makefile

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1-
export ARCH=arm
2-
CC = ~/basic/cross_compile/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-gcc
3-
#CC = gcc
4-
CFLAGS = -O2 -Wall --static
1+
ARCH = x86
2+
#ARCH = arm
3+
ifeq ($(ARCH), arm)
4+
export ARCH=arm
5+
CC = ~/basic/cross_compile/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-gcc
6+
else
7+
CC = gcc
8+
endif
9+
10+
CFLAGS = -O2 --static -DDBG_TEST
511
INCLUDE = -I ./include
612

7-
all:mmap hello
13+
all:mmap hello product-consumer
814

915
mmap:mmap.o
1016
${CC} ${CFLAGS} mmap.o -o $@
1117
rm -rf *.o
1218
hello:hello.o
1319
${CC} ${CFLAGS} hello.o -o $@
14-
20+
product-consumer:product-consumer.o
21+
${CC} ${CFLAGS} product-consumer.o -o $@ -lpthread
1522
clean:
16-
rm -rf *.o mmap
23+
rm -rf *.o mmap hello product-consumer

helper/linux/hello

-576 KB
Binary file not shown.

helper/linux/hello.o

-1.14 KB
Binary file not shown.

helper/linux/product-consumer.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <stdbool.h>
4+
#include <string.h>
5+
#include <time.h>
6+
#include <unistd.h>
7+
#include <pthread.h>
8+
9+
#define MAXLENGTH 10 //the maxlength of queue
10+
11+
typedef char * datatype;
12+
typedef struct node { //define node
13+
datatype name;
14+
struct node *next;
15+
} node;
16+
typedef struct queue { //define queue
17+
node *front, *rear;
18+
int len;
19+
} queue;
20+
21+
void queue_init(queue *q)
22+
{
23+
q->front = q->rear = NULL;
24+
q->len = 0;
25+
}
26+
27+
void queue_put(queue *q, datatype new_name)//入队
28+
{
29+
node *mynode = (node *)malloc(sizeof(node));
30+
mynode->name = new_name;
31+
mynode->next = NULL;
32+
if (q->rear)
33+
q->rear->next = mynode;
34+
q->rear = mynode;
35+
if (q->front == NULL)
36+
q->front = mynode;
37+
q->len++;
38+
}
39+
40+
datatype queue_get(queue *q) //出队
41+
{
42+
node *mynode;
43+
datatype myname;
44+
if (q->front != NULL)
45+
mynode = q->front;
46+
myname = mynode->name;
47+
q->front = q->front->next;
48+
q->len--;
49+
free(mynode);
50+
return myname;
51+
}
52+
53+
void queue_print(queue *q) //print queue
54+
{
55+
node *tmp = q->front;
56+
while(tmp != NULL)
57+
{
58+
printf("%s ", tmp->name);
59+
tmp = tmp->next;
60+
}
61+
printf("\n");
62+
}
63+
64+
/*生产者与消费者函数*/
65+
/*define mutex and condtion var*/
66+
pthread_cond_t q_not_full = PTHREAD_COND_INITIALIZER;
67+
pthread_cond_t q_not_empty = PTHREAD_COND_INITIALIZER;
68+
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
69+
70+
/*
71+
* producer function
72+
*/
73+
void producer(void *q)
74+
{
75+
// printf("start porducer:\n");
76+
queue *qt = q; //传入的队列
77+
while(1)
78+
{
79+
pthread_mutex_lock(&qlock);
80+
// printf("producer has locked the qlock\n");
81+
while(qt->len >= MAXLENGTH) //queue is full
82+
{
83+
// printf("producer is going to waiting\n");
84+
pthread_cond_wait(&q_not_full, &qlock);
85+
}
86+
queue_put(qt, "* ");
87+
// printf("after producer: queue's length is %d\n", qt->len);
88+
pthread_mutex_unlock(&qlock);
89+
pthread_cond_signal(&q_not_empty);
90+
91+
// printf("producer has unlocked the qlock\n");
92+
// sleep(1);
93+
}
94+
}
95+
96+
/*
97+
* consumer function
98+
*/
99+
void consumer(void *q)
100+
{
101+
// printf("start consumer:\n");
102+
queue *qt = q;
103+
while(1)
104+
{
105+
pthread_mutex_lock(&qlock);
106+
// printf("consumer has locked the qlock\n");
107+
while(qt->len <= 0) //queue is empty
108+
{
109+
// printf("consumer is going to waiting\n");
110+
pthread_cond_wait(&q_not_empty, &qlock);
111+
}
112+
datatype back_name = queue_get(qt);
113+
// printf("after consumer, queue's length is %d\n", qt->len);
114+
pthread_mutex_unlock(&qlock);
115+
pthread_cond_signal(&q_not_full);
116+
// now process the back_name
117+
// printf("cousumer has unlocked the qlock\n");
118+
// sleep(1);
119+
}
120+
}
121+
122+
//gcc编译时加上-lpthread
123+
int main() {
124+
pthread_t tid1, tid2;
125+
queue *q=(queue *)malloc(sizeof(queue));
126+
queue_init(q);
127+
128+
#ifdef DBG_TEST
129+
queue_put(q, "one");
130+
queue_put(q, "two");
131+
queue_put(q, "three");
132+
queue_get(q);
133+
printf("len = %d\n", q->len);
134+
queue_print(q);
135+
#endif
136+
long stime = clock();
137+
long etime = clock();
138+
139+
pthread_create(&tid1, NULL, (void *)producer, (void *)q);
140+
pthread_create(&tid2, NULL, (void *)consumer, (void *)q);
141+
142+
while((float)(etime-stime)/CLOCKS_PER_SEC < 0.00001)
143+
{
144+
etime = clock();
145+
}
146+
return 0;
147+
}

0 commit comments

Comments
 (0)
0