- 主题:两个进程一个只写一个只读一个文件,如何保证读到完整数据
我定义了一个struct, 24byte, 每次调用fwrite(&buf, 24, 1, fw)来写24byte到文件中(binary mode)
在读进程中,我用fread(&buf, 24, 1, fr)来读,但我发现在某些时候,会读失败,可能读到少于24个bytes, 然后我也没办法把读到的数据退回到字符流中,所以后面再读时,整个序列全乱了,
不知道有什么办法可以解决这个问题,而不牺牲性能。
我主要是想一个进程写, 写完就尽快退出。
读尽量早的开始,读出来二进制数据后,格式化输出成可读log
--
FROM 64.207.220.*
说一下,我的方案,其实只要每次读前保存一下文件指针,如果读失败就回退指针。 这样就可以避免读到不完整的数据了
--
FROM 64.207.220.*
我知道用shared memory性能好, 或者其他的
但shared memory需要定义shared memory name, 当crash时, 需要清理/dev/shared memory
当有多个实例时,也需要保证一一匹配。
socket需要定义好socket port, 保证两个进程一一对应。
我的场景其实是运行verilog仿真,然后通过DPI-C来把数据写到磁盘上,为了节省时间,我就写成binary格式, 然后再通过另一个进程来把binary格式写成另一个EDA tools需要的格式。
如果我在DPI-C中用另一个线程来做format, 这样我的仿真主线程就退不出,所以我考虑用一个独立的进程来做。
总体来说我为了方便性, 所以用了最土的方法。
【 在 lwp 的大作中提到: 】
: 你是有什么理由一定要用文件做进程通信么?
--
FROM 64.207.220.*
我的producer(writer)其实是emulator, 它比consumer(reader/formater)快, 我希望当仿真运行完后, emulator资源可以释放。
所以我觉得我还是需要用文件来保存数据, 共享内存或socket, message等方式都不行
【 在 lipp 的大作中提到: 】
: 在共享内存里开ring buffer,开大点。
: 写索引和读索引。
: 读进程一次性多读一些数据,避免高频写硬盘。
--
FROM 64.207.220.*
文件名是约定好的, 会先读取一个配置方件(这个是约定的)
配置文件约定写出的文件名
即使有多个实例跑的话, 也是会有多个文件夹的,log都生成在运行目录,这个不会冲突。
主要问题是做为producer的是emulator, 我需要它跑完就尽快退出,而不是在这边等consumer。
实际上如果不是因为这个需求,我就在producer里把数据直接生成为另一个工具需要的格式, 根本不需要做producer-consumer这种方式了。
我的一个小例子, 通过让producer写成binary的文件(不做格式化),可以让producer侧从原来的20 sec, 减少到12 sec左右。
而原来的20 sec中有12 sec左右都是C侧在格式化和写磁盘, 硬件emulator真正运行的时间很短。 当case变大后, 一个10分钟的case(无C侧写), 变会变成2个多小时
【 在 jimmycmh 的大作中提到: 】
: 这些都不是理由吧,用文件crash时也要清理旧文件,也要进程间约定文件名,没有比共享内存或管道更简单
: 回到你这个问题,应该是因为没有flush到磁盘吧,操作系统按页落盘,可能某条记录跨页了,主动flush一下
:
--
FROM 64.207.220.*