• R语言软件
  • R语言中多线程写文件,如何保证数据安全?

最近使用 win10+R 组合在分析全球气象数据,用到了doParallel的foreach函数分析数据之后写入文件保存结果,在这过程中有多次写入的过程,这个时候就会出现数据丢失和错乱的情况。

请问,在R多线程处理中如何避免不同线程写入同一个文件时的数据安全呢?多谢~

写同一个文件很难保证,最好是同时写多个,后期再合并。

    如果内存装得下的话,先把结果统一存内存里,循环完成再保存结果

      我的办法比较土,一般我在并行写同一个文件时,采用的办法是写一个指示文件,就像 R 安装包时创建的 00LOCK 文件一样;对每个线程或进程,它写文件之前先检查一下这个指示文件是否存在,如果不存在,那么就创建它(相当于声明“现在我占着茅坑,其他人都不要来”),然后开始写你要写的文件,写完之后删掉这个指示文件;其它线程如果发现这个指示已经存在,就先等待着,一直等到指示文件消失,然后就轮到它们来写新的内容了。

      这个办法可能也无法避免多个线程恰巧(不管这个概率多低)同时发现指示文件存在或不存在的情况,然后撞车。所以安全起见,最好还是不要所有线程写同一个文件,而是要么如 2 楼所说,各自写各自的文件,完事之后再回到主线程合并结果,要么如 3 楼所说,结果都存在内存里,完事后再合并了一起写。

        谢谢各位大拿yihui tctcab Ihavenothing
        数据量比较大,得有>1T了,文件数量也比较多,8万多,如果再拆分一下,量有点大。

        今天上午采用了和益辉类似的方法,也是比较笨的,思路如下:
        首先按照规则生成这8万个文件,可以是空的;
        然后启动多线程处理,首先判断目标文件是否存在。当某个线程处理到这个文件时,立即将文件名修改,然后将数据写入;结束后将文件名改回来。

        当另外的线程也碰到了某个文件正好在被其它线程操作时,理论上它是找不到这个文件的,因为文件名被改掉了。所以当前线程就while循环判断文件是否存在,直到上一个线程将文件释放出来。

        目前测试了部分的数据,好像正常(理论上确实存在那么一瞬间两个线程同一时刻处理同一个文件,后期处理时再看看)

        以前处理一年的数据需要12小时,现在估计不到1小时,还在继续思考如何再优化提高速度😃

          qingyi

          大量的磁盘读写是很费时的,我觉得你需要SQL之类的数据库,然后用R的SQL接口做数据处理

            tctcab 在使用文本存储数据之前,我也一直是使用SQL数据库存数据的,可是遇到了问题是,当数据量超过一定的时候,查询起来就非常费时。我记得有一次是气象观测数据,数据量应该在千万,每查询一次就歇菜。

            不知道是不是我设计的不合理,您有啥文献或者资料可以参考的不

              多进程并行写同一个文件理论上就是不可能安全的吧…… 加个自旋锁几乎是保证安全的唯一方式。本质来说加锁就是为了把并行写改成串行写。按照这个思路优化,可以在中间加一层缓存机制,先写到内存里,积累到一定大小再由一个进程统一写到文件里,这样就通过减少了写的次数提高了平均写入性能。

                nan.xiao 学习了自旋锁,看来这个问题是做并行的人常遇到的。

                测试了自己那个改文件名的方法,跑了三年的数据,耗时6个小时,而且大概有5%的错误,错误率有点高,而且数据有四十年的,累积起来就无法接受错误的比例了。

                还得再琢磨琢磨咋整:c,不过老哥说的减少写入次数估计是个方向

                3 年 后

                frankzhang21 我最近做并行也遇到了相同问题。想请问一下sparklyr怎么实现呀,感觉我只需要一个能并行写入的数据库就行