当前位置: 技术问答>linux和unix
关于fifo的问题
来源: 互联网 发布时间:2017-01-11
本文导语: 于事,所以选择用fifo进行缓冲,这个时候视频流依然不完整,反而以前的低码率也没办法保证完整性。 现在有三个可能: 第一个:接受udp慢,导致丢包。 第二个:fifo异常 第三个:上层应用编写不正确。 针对第一...
于事,所以选择用fifo进行缓冲,这个时候视频流依然不完整,反而以前的低码率也没办法保证完整性。
现在有三个可能:
第一个:接受udp慢,导致丢包。
第二个:fifo异常
第三个:上层应用编写不正确。
针对第一个:
我选择创建两个线程,一个不同的在socket上读并写道fifo里面。另外一个线程,从fifo里面读,写入文件。结果没出现任何异常。
针对第三个:
我的做法是,上层应用不从fifo里面读数据,而是从给定的视频文件里面读取。显示正常,没有出现任何错误。
所以可以确定是 fifo 缓冲不当造成的问题了。请问如何解决?
对了我发送视频的码率是 (37 Mbps(4.5MBps左右) )
fifo会溢出不?
现在有三个可能:
第一个:接受udp慢,导致丢包。
第二个:fifo异常
第三个:上层应用编写不正确。
针对第一个:
我选择创建两个线程,一个不同的在socket上读并写道fifo里面。另外一个线程,从fifo里面读,写入文件。结果没出现任何异常。
针对第三个:
我的做法是,上层应用不从fifo里面读数据,而是从给定的视频文件里面读取。显示正常,没有出现任何错误。
所以可以确定是 fifo 缓冲不当造成的问题了。请问如何解决?
对了我发送视频的码率是 (37 Mbps(4.5MBps左右) )
fifo会溢出不?
|
楼主选择用fifo的原因肯定是考虑了UDP报文形式和消息队列的msg是统一的,所以毫不犹豫的选择了fifo。
楼主的问题多么简单啊,一个进程里2个线程间传递数据包。
网络线程读了一个UDP包,加锁放入循环队列。
文件线程加锁检测循环队列,有就取走,没有就阻塞在条件变量上。
楼主又会问了,我是UDP报文啊,放到队列里咋办啊?
你可以把队列做成char* queue[N]; 保证queue[i]指向的内存足够容纳一个UDP包。
也可以把队列做成字节流的:char queue[N*MAX_SIZE_PER_UDP]; 放进去的时候在UDP包前面加上4字节的int size;就行了。
如果你觉得不用fifo会面临一个严重的问题,那就是网络线程数据太多,循环队列满了怎么办啊??
那么必须拿出绝招了,用pipe交互数据+I/O复用:
网络线程的UDP包带上int size的头部一起写入pipe,如果pipe容量不足或者已经满了,我们根据返回值,将没有写入的部分存到应用层buffer里,注册I/O复用的write事件。 等I/O复用通知我们可写我们才写,当然此时网络SOCKET的检测也是交给这个I/O复用了。
楼主的问题多么简单啊,一个进程里2个线程间传递数据包。
网络线程读了一个UDP包,加锁放入循环队列。
文件线程加锁检测循环队列,有就取走,没有就阻塞在条件变量上。
楼主又会问了,我是UDP报文啊,放到队列里咋办啊?
你可以把队列做成char* queue[N]; 保证queue[i]指向的内存足够容纳一个UDP包。
也可以把队列做成字节流的:char queue[N*MAX_SIZE_PER_UDP]; 放进去的时候在UDP包前面加上4字节的int size;就行了。
如果你觉得不用fifo会面临一个严重的问题,那就是网络线程数据太多,循环队列满了怎么办啊??
那么必须拿出绝招了,用pipe交互数据+I/O复用:
网络线程的UDP包带上int size的头部一起写入pipe,如果pipe容量不足或者已经满了,我们根据返回值,将没有写入的部分存到应用层buffer里,注册I/O复用的write事件。 等I/O复用通知我们可写我们才写,当然此时网络SOCKET的检测也是交给这个I/O复用了。