- 主题:两个进程一个只写一个只读一个文件,如何保证读到完整数据
推荐用消息,比如zmq
消息复杂的话上protobuf
【 在 eematlab 的大作中提到: 】
: 我定义了一个struct, 24byte, 每次调用fwrite(&buf, 24, 1, fw)来写24byte到文件中(binary mode)
: 在读进程中,我用fread(&buf, 24, 1, fr)来读,但我发现在某些时候,会读失败,可能读到少于24个bytes, 然后我也没办法把读到的数据退回到字符流中,所以后面再读时,整个序列全乱了,
: 不知道有什么办法可以解决这个问题,而不牺牲性能。
: ...................
--
FROM 162.156.156.*
单数秒读,双数秒写,如果读写都很快
【 在 eematlab 的大作中提到: 】
: 我定义了一个struct, 24byte, 每次调用fwrite(&buf, 24, 1, fw)来写24byte到文件中(binary mode)
:
: 在读进程中,我用fread(&buf, 24, 1, fr)来读,但我发现在某些时候,会读失败,可能读到少于24个bytes, 然后我也没办法把读到的数据退回到字符流中,所以后面再读时,整个序列全乱了,
: ....................
- 来自「最水木 for iPhone 8 Plus」
--
FROM 61.181.219.*
正解,文件锁应该是最安全的
【 在 somebody 的大作中提到: 】
: 加锁
- 来自「最水木 for iPhone 6s Plus」
--
FROM 123.125.37.*
这些都不是理由吧,用文件crash时也要清理旧文件,也要进程间约定文件名,没有比共享内存或管道更简单
回到你这个问题,应该是因为没有flush到磁盘吧,操作系统按页落盘,可能某条记录跨页了,主动flush一下
【 在 eematlab (一辰未冉) 的大作中提到: 】
: 我知道用shared memory性能好, 或者其他的
: 但shared memory需要定义shared memory name, 当crash时, 需要清理/dev/shared memory
: 当有多个实例时,也需要保证一一匹配。
: ...................
--
FROM 115.171.244.*
我的producer(writer)其实是emulator, 它比consumer(reader/formater)快, 我希望当仿真运行完后, emulator资源可以释放。
所以我觉得我还是需要用文件来保存数据, 共享内存或socket, message等方式都不行
【 在 lipp 的大作中提到: 】
: 在共享内存里开ring buffer,开大点。
: 写索引和读索引。
: 读进程一次性多读一些数据,避免高频写硬盘。
--
FROM 64.207.220.*
writer退出后,共享内存仍然存在,直到所有reader都退出。
既然你读得没有写的快,那必然要有个大缓存。你只要做读写同步,就会拖延写速度。
【 在 eematlab (一辰未冉) 的大作中提到: 】
: 我的producer(writer)其实是emulator, 它比consumer(reader/formater)快, 我希望当仿真运行完后, emulator资源可以释放。
: 所以我觉得我还是需要用文件来保存数据, 共享内存或socket, message等方式都不行
--
FROM 123.103.9.*
文件名是约定好的, 会先读取一个配置方件(这个是约定的)
配置文件约定写出的文件名
即使有多个实例跑的话, 也是会有多个文件夹的,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.*
consumer读之前先测试能不能读到整个struct啊
【 在 eematlab 的大作中提到: 】
: 文件名是约定好的, 会先读取一个配置方件(这个是约定的)
: 配置文件约定写出的文件名
: 即使有多个实例跑的话, 也是会有多个文件夹的,log都生成在运行目录,这个不会冲突。
: ...................
--
FROM 178.26.114.*
用管道是最简单的吧,父进程启动子进程,再往子进程的标准输入中写数据,子进程内部从标准输入中读数据(调用 scanf,Console.Readline 之类的函数就能读取到)。
或者 A 进程数据写到标准输出,B进程从标准输入读数据,再调用 A.exe | B.exe ,就搞定。
--
修改:missmary FROM 124.160.68.*
FROM 124.160.68.*
读那头都是要加循环的,读不够的时候接着读剩下的啊。
【 在 eematlab 的大作中提到: 】
: 说一下,我的方案,其实只要每次读前保存一下文件指针,如果读失败就回退指针。 这样就可以避免读到不完整的数据了...
※ 来源:·
https://exp.newsmth.net·[FROM: 123.113.181.*]
FROM 123.113.181.*