C 語言中實現(xiàn)環(huán)形緩沖區(qū)
1.實現(xiàn)代碼:
#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指向存放數(shù)據(jù)的緩沖區(qū),size是緩沖區(qū)的大小,in是寫指針下標,out是讀指針下標,在len和(fifo->size - fifo->in + fifo->out)之間取一個較小的值賦給len。注意,當(fifo->in == fifo->out+fifo->size)時,表示緩沖區(qū)已滿,此時得到的較小值一定是0,后面實際寫入的字節(jié)數(shù)也全為0。另一種邊界情況是當len很大時(因為len是無符號的,負數(shù)對它來說也是一個很大的正數(shù)),這一句也能保證len取到一個較小的值,因為fifo->in總是大于等于fifo->out,所以后面的那個表達式的值不會超過fifo->size的大小把上一步?jīng)Q定的要寫入的字節(jié)數(shù)len“切開”,這里又使用了一個技巧。注意:實際分配給fifo->buffer的字節(jié)數(shù)fifo->size,必須是2的冪,否則這里就會出錯。既然fifo->size是2的冪,那么 (fifo->size-1)也就是一個后面幾位全為1的數(shù),也就能保證(fifo->in & (fifo->size - 1))總為不超過(fifo->size - 1)的那一部分,和(fifo->in)% (fifo->size - 1)的效果一樣。
2.這樣后面的代碼就不難理解了,它先向fifo->in到緩沖區(qū)末端這一塊寫數(shù)據(jù),如果還沒寫完,在從緩沖區(qū)頭開始寫入剩下的,從而實現(xiàn)了循環(huán)緩沖。最后,把寫指針后移len個字節(jié),并返回len。
3.從上面可以看出,fifo->in的值可以從0變化到超過fifo->size的數(shù)值,fifo->out也如此,但它們的差不會超過fifo->size 。
以上就是環(huán)形緩沖區(qū)域的C語言實現(xiàn)詳解,希望對大家有所幫助,謝謝支持!
上一篇:C++面試題之數(shù)a、b的值互換(不使用中間變量)
欄 目:C語言
本文標題:C 語言中實現(xiàn)環(huán)形緩沖區(qū)
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2185.html
您可能感興趣的文章
- 04-02c語言函數(shù)調用后清空內(nèi)存 c語言調用函數(shù)刪除字符
- 04-02c語言的正則匹配函數(shù) c語言正則表達式函數(shù)庫
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對數(shù)怎么表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段函數(shù)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排序法函數(shù)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段函數(shù)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 04-02c語言調用函數(shù)求fibo C語言調用函數(shù)求階乘


閱讀排行
本欄相關
- 04-02c語言函數(shù)調用后清空內(nèi)存 c語言調用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調用函數(shù)求fibo C語言調用函數(shù)求
隨機閱讀
- 01-10C#中split用法實例總結
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery


