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)詳解,希望對大家有所幫助,謝謝支持!
相關(guān)文章
如何判斷一個數(shù)是否為2的冪次方?若是,并判斷出來是多少次方?
本篇文章是對如何判斷一個數(shù)是否為2的冪次方?若是,并判斷出來是多少次方的實現(xiàn)方法,進行了詳細的分析介紹,需要的朋友參考下2013-05-05