今天为多进程采集写了一个任务调度的程序,然后写了一个测试代码,取得任务之后用error_log写下进程号、任务ID就继续取下一个任务。
开了10个进程进行测试,每次100000条任务,实际上打出来的error_log总是不到100000,大概差10-30条。我尝试着在每两个任务之间sleep几毫秒,丢失的任务记录会少一些,但是也会丢失10几条。
进程调度程序本身怎么找都找不到问题,最后我把怀疑的目光投向了error_log这个函数。这次我不用调度程序,10个进程,每个都直接error_log输出1-10000,结果一看,同样会丢失20条左右的记录。
我自己写了一段写log的代码,再次通过进程调度,这次就一条也不少了。
实践证明:error_log()这个函数在高并发同时写入一个文件时会丢失部分内容。
然后我又写了一个测试脚本,测试10000次写入的速度:
error_log:
7.39、6.97、7.28、8.99、7.02、7.30、7.26、7.39、7.35(平均耗时:7.44秒)
fwrite(不锁定):
8.19、8.15、7.36、7.49、9.96、7.27、7.51、6.93、7.29(平均耗时:7.79秒)
fwrite(锁定):
7.88、7.91、8.44、8.99、8.44、8.56、7.84、7.93、7.93(平均耗时:8.21秒)
通过测试数据可以看出三种方法的速度相差不大,error_log最快,fopen之后锁定写入最慢。大部分情况下error_log都能够满足要求,只有当写入特别频繁而且数据可靠性要求比较高的情况下才需要用第三种方法。