关键词:Java 多进程 Rutime clang klee llvm Process类 waitFor()方法
-
场景描述:
用Rutime.getRuntime().exec(cmd)执行四条命令行,前三条命令行生成三个文件:file1.bc、file2.bc、file3.bc。最后一条命令行是把前三个命令行执行生成的三个.bc文件集成link成一个大的bc文件:bigtask.bc,为后续klee去生成.ktest做准备。 -
问题现象:
当四行命令首次顺序执行的时候,生成的bigtask.bc文件大小只有19kb,第二次执行覆盖操作顺序执行四条命令行生成的bigtask.bc文件大小问21kb,之后继续重复上述操作,bigtask.bc文件大小都稳定在21kb,通过比对文件发现,第一次生成的bigtask.bc和后续生成的bigtask.bc文件内容确实不一样,第一次生成的文件有部分内容缺失,生成不完整。 -
分析原因及解决方案:
四条命令行都是调用封装的同一个Rutime.getRuntime().exec(cmd)顺序执行,单线程不存在线程竞争问题,但是有一个细节操作就是,第四条命令行生成bigtask.bc文件在执行前会new 一个 File()的io,去先前生成的三哥bc文件目录下,读到三个文件名后再生成最后一条命令给Rutime.getRuntime().exec(cmd)去执行,而此时Rutime.getRuntime().exec(cmd)会创建一个进程,读文件目录的io操作也会创建一个进程,这两个进程的先后顺序完全取决于cpu时间片的分配多少先后顺序,而cpu的这个操作是随机的,可能第一个文件第二个文件bc文件成功生成,但是第三个bc文件还没来得及生成,此时new File()去目录下读bc文件个数就会少一个,此时集成生成的bigtask文件的命令是不完整,缺少第三个文bc文件的指向,从而生成的bigtask.bc文件缺失导致大小为19kb,而后续重新生成是覆盖操作,上一次已经完整生成了三个bc文件,所以无论执行多少次覆盖重新生成的操作生成的bigtask.bc文件都是21kb,文件内容完整。
故我们可以用Process类的waitFor()方法
来监视exec(cmd)的执行情况,设置一个超时时间,让后面的命令执行前确保前面的命令已经执行完毕了,这样就可以了。
原来Runtime().exec()除代码为:
Runtime.getRuntime().exec(cmd);
修改后的为
Process exec = Runtime.getRuntime().exec(cmd);
exec.waitFor(10, TimeUnit.SECONDS);