FIFO的数组实现方式
来源:互联网 发布:考研网络辅导班 编辑:程序博客网 时间:2024/05/01 02:30
1 背景
在Linux中,可以使用库函数mkfifo()创建FIFO,然后可以使用read()/write()系统调用来对其进行读/写操作。然而,如果读写操作比较频繁(例如不同线程间需要不断的传输数据),则会使得程序的效率比较低(由于需要频繁的执行系统调用read()/write())。因此,如果能够使用数组来实现FIFO,则对提高程序的效率具有重要的意义。
2 实现方法
根据上述背景,参考资料[1]给出了相应的实现方法,但是并没有很好的解决下标循环的问题(即不能保证所读取的是最早进入队列的数据,甚至有可能是最新的)。
2.1 读写单个字符
见《Linux多线程编程》第4章实例。
2.2 读写多个字符
根据参考资料[1],实现了一次读写多个字符的版本如下。
#include <stdio.h>#include <stdint.h>#include <pthread.h>#include <unistd.h>#include <string.h>#include <stdbool.h>#define FIFO_LENGTH 1024static char fifo_buffer[ FIFO_LENGTH ];static uint16_t front = 0;static uint16_t rear = 0;static void *write_thread( void* );static void *read_thread( void* );static bool fifo_write( char* buffer, uint16_t wr_len );static bool fifo_read(char* buffer, uint16_t rd_len );static pthread_rwlock_t q_lock;int main(int argc, char*argv[]){pthread_t wr_th;pthread_t rd_th;pthread_rwlock_init( &q_lock, NULL);pthread_create( &wr_th, NULL, write_thread, NULL );pthread_create( &rd_th, NULL, read_thread, NULL );pthread_join(wr_th, NULL);pthread_rwlock_destroy( &q_lock );return 0;}void *write_thread( void*arg ){int i;char buffer[] = "0123456789abcdefg";for( i = 0; i < 1000; i++) {if ( !fifo_write( buffer, sizeof( buffer ) - 1 ) )fprintf(stderr, "fifo_write error\n");sleep( 1 );}return (void*)0;}void *read_thread( void*arg ){char buffer[10];while( 1 ) {memset(buffer, 0, 10);if ( fifo_read( buffer, 10) )printf("%s\n", buffer);else{usleep( 1000 );}}return (void*)0;}bool fifo_write( char* buffer, uint16_t wr_len ){if (wr_len > FIFO_LENGTH -1)return false;uint16_t empty_len;uint16_t tmp_addr;uint16_t tmp_len;empty_len = ( front + FIFO_LENGTH - ( rear + 1) ) % FIFO_LENGTH;if ( empty_len >= wr_len ){ // wr_lock pthread_rwlock_wrlock( &q_lock ); tmp_addr = ( rear + wr_len) % FIFO_LENGTH; if (tmp_addr <= rear) //If Circular array have inverse to begin. { tmp_len = wr_len - tmp_addr; memcpy(&fifo_buffer[ rear ], buffer, tmp_len); //bug place memcpy(&fifo_buffer[0], buffer + tmp_len, tmp_addr); } else { memcpy(&fifo_buffer[ rear ], buffer, wr_len); } rear = tmp_addr; // unlock pthread_rwlock_unlock( &q_lock ); return true;}return false;}bool fifo_read(char*buffer, uint16_t rd_len ){ uint16_t valid_len; uint16_t tmp_addr; uint16_t tmp_len; valid_len = ( rear + FIFO_LENGTH - front ) % FIFO_LENGTH; if ( valid_len >= rd_len) { pthread_rwlock_wrlock( &q_lock ); tmp_addr = ( front + rd_len ) % FIFO_LENGTH; if ( tmp_addr <= front ) { tmp_len = rd_len - tmp_addr; memcpy( buffer, &fifo_buffer[ front ], tmp_len); memcpy( buffer + tmp_len, &fifo_buffer[ 0 ], tmp_addr); } else { memcpy( buffer, &fifo_buffer[ front ], rd_len ); } front = tmp_addr; pthread_rwlock_unlock( &q_lock ); return true; } return false;}
参考资料
[1]C语言循环数组做FIFO队列--一些认识
0 0
- FIFO的数组实现方式
- FIFO实现:数组方式
- FIFO通信的方式
- 串口中断方式实现FIFO
- FIFO 队列的链表和数组实现
- FIFO 队列的链表和数组实现
- FIFO 队列的链表和数组实现
- FIFO的实现
- 管道,FIFO的实现
- FIFO的FPGA实现
- FIFO的FPGA实现
- FIFO队列实现-------循环数组实现
- 【算法】用固定数组实现FIFO buffer
- 多任务FIFO的实现
- 异步FIFO的FPGA实现
- 异步FIFO的FPGA实现
- 异步FIFO的FPGA实现
- 队列的实现(FIFO、链表)
- Sqoop对Mysql数据库导入导出到hdfs(基于Hadoop 2.6.0 )
- Xcode6.3 如何使用Leaks查看内存泄露
- HDU 2082 找单词
- 2012年5月SAT香港真题解析
- 杭电 hdu Warm up 2 (二分匹配)
- FIFO的数组实现方式
- hdu2018 (递归,记忆化递归)
- @Resource注解
- 程序设计《银行系统》
- 使用 JQueryMobile 点击超链接提示“error loading page” 错误
- 关于Java传值和传址的一些讨论
- [Jsoup] Jsoup解析中需要注意的问题
- day03--面向对象--设计模式之单例模式
- 基于Spring-SpringMVC-Mybatis的简单例子