FIFO 非阻塞写+非阻塞读+延时循环读的一种方法

用mkfifo在当前目录下建立一个myfifo的有名管道


只运行非阻塞写的程序 open参数为O_WRONLY | O_NONBLOCK
write失败,这是man手册里面说明了的情况


如果open参数为O_RDWR | O_NONBLOCK
写程序则可以立即返回
但是当运行完写程序之后再运行读程序,发现没有从管道里读出任何数据出来。
也就是说管道里面是空的,没有存入任何数据。
写程序中判断了write的返回值,不是-1


如果open参数为O_WRONLY
则为写阻塞
当执行读程序的时候写程序才会返回


当读程序中的open参数为O_RDONLY
这时候是读阻塞
当先运行读程序的时候,写程序是不是阻塞的无所谓,都可以读到数据
但是,非阻塞的写,是没法读到数据的。似乎非阻塞的写没有把数据写入管道中。后面证明,是读需要多次才能读到,这中间存在了一个准备时间之类东西……


设置读程序中open的参数为O_RDWR|O_NONBLOCK
这时候是非阻塞读管道
当没有任何写程序执行的时候read返回-1,错误码是EAGAIN
当写是阻塞写的时候,非阻塞读依然不能读到数据


写的open参数为O_RDWR的时候即为非阻塞写


阻塞读+非阻塞写的组合可以读到数据,先进行读
阻塞读+阻塞写的组合可以读到数据,无所谓谁先运行
非阻塞读+任何写的方法,都不能读到数据

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Verilog代码,实现了一个没有延时fifo: ```verilog module fifo ( input clk, input reset, input write_en, input [7:0] write_data, output reg empty, output reg full, output reg [7:0] read_data, input read_en ); parameter WIDTH = 8; parameter DEPTH = 16; reg [WIDTH-1:0] mem [0:DEPTH-1]; reg [4:0] head = 0; reg [4:0] tail = 0; reg [4:0] count = 0; always @(posedge clk) begin if (reset) begin head <= 0; tail <= 0; count <= 0; empty <= 1; full <= 0; end else begin if (write_en && !full) begin mem[head] <= write_data; head <= head + 1; count <= count + 1; empty <= 0; if (count == DEPTH) begin full <= 1; end end if (read_en && !empty) begin read_data <= mem[tail]; tail <= tail + 1; count <= count - 1; full <= 0; if (count == 1) begin empty <= 1; end end end end endmodule ``` 该代码使用一个双端队列(circular queue)实现了一个FIFO。双端队列具有一个头指针(head)和一个尾指针(tail),入数据时将数据存储在头指针对应的位置,头指针向后移动一位,取数据时将尾指针对应的数据出,尾指针向后移动一位。当头指针和尾指针相遇时,可以通过将头指针或尾指针移回队列的起始位置来实现循环队列的效果。队列的状态包括当前队列中的元素数量(count)和队列是否为空或已满(empty和full)。在入或取数据时,需要检查队列是否已满或为空,以避免数据覆盖或取错误。 需要注意的是,这个FIFO没有延时,因此取到的数据是上一个时钟周期入的数据。如果需要延时,可以在取数据时将数据暂存,并在下一个时钟周期输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值