在阅读APUE(第3版)一书时,我遇到了开放式系统调用及其允许用户使用O_APPEND模式打开文件进行写入原子操作的能力,这意味着多个进程可以写入文件描述符并且内核确保写入的数据通过多个进程到单个文件,不重叠,所有行都完好无损.
在使用C/C++程序成功进行开放式系统调用试验后,我能够对其进行验证,并且它就像书中描述的那样工作.我能够启动多个写入单个文件的进程,并且所有行都可以将w.r.t计入其进程PID.
我希望与perl sysopen一起观察相同的行为,因为我在工作中有一些任务可能会受益于这种行为.尝试了,但实际上没有用.当我分析输出文件时,我能够看到竞争条件的迹象(可能),因为有很多次交错行.
问题:perl sysopen调用与linux的开放系统调用不一样吗?是否有可能通过多个进程将单一文件的这种类型的原子写操作实现?
编辑:添加C代码和用于测试的perl代码.
C/C++代码
int main(void)
{
if ((fd = open("outfile.txt",O_WRONLY|O_CREAT|O_APPEND)) == -1) {
printf ("Failed to create outfile! exiting!\n");
return -1;
}
for (int counter{1};counter<=MAXLINES;counter++)
{ /* write string 'line' for MAXLINES no. of times */
std::string line = std::to_string(ACE_OS::getpid())
+ " This is a sample data line ";
line += std::to_string(counter) + " \n";
if ((n = write(fd,line.c_str(),strlen(line.c_str()))) == -1) {
printf("Failed to write to outfile!\n";
}
}
return 0;
}
Perl代码
#!/usr/bin/perl
use Fcntl;
use strict;
use warnings;
my $maxlines = 100000;
sysopen (FH,"testfile",O_CREAT|O_WRONLY|O_APPEND) or die "Failed sysopen\n";
while ($maxlines != 0) {
print FH "($$) This is sample data line no. $maxlines\n";
$maxlines--;
}
close (FH);
__END__
更新(初始故障排除后):
感谢下面答案中提供的信息,我能够让它运作起来.虽然我遇到了一些缺失行的问题,这些行是由于我用O_TRUNC打开每个进程的文件引起的,我不应该这样做,但最初错过了它.经过一些仔细的分析 – 我发现了问题并纠正了它.一如既往 – linux永远不会让你失望:)
这是我用来启动进程的bash脚本:
#!/bin/bash
# basically we spawn "$1" instances of the same
# executable which should append to the same output file.
max=$1
[[ -z $max ]] && max=6
echo "creating $max processes for appending into same file"
# this is our output file collecting all
# the lines from all the processes.
# we truncate it before we start
>testfile
for i in $(seq 1 $max)
do
echo $i && ./perl_read_write_with_syscalls.pl 2>>_err &
done
# end.
从输出文件验证:
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$ ls -lrth testfile
-rw-rw-r--. 1 compuser compuser 252M Jan 31 22:52 testfile
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$ wc -l testfile
6000000 testfile
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$ cat testfile |cut -f1 -d" "|sort|uniq -c
1000000 (PID: 21118)
1000000 (PID: 21123)
1000000 (PID: 21124)
1000000 (PID: 21125)
1000000 (PID: 21126)
1000000 (PID: 21127)
[compuser@lenovoe470:07-multiple-processes-append-to-a-single-file]$
观察:
令我惊讶的是,系统上没有任何等待平均负载 – 根本没有.我没想到.我相信内核必须已经处理过,但不知道它是如何工作的.我有兴趣了解更多相关信息.
这可能是什么应用?
我做了很多文件来进行文件协调,我们(在工作中)总是需要解析大量的数据文件(例如30gb – 50gb).有了这个工作 – 我现在可以做并行操作,而不是我以前的方法,包括:散列文件1,然后散列文件2,然后比较2个文件中的键,值对.现在我可以并行执行散列部分并缩短所需的时间 – 甚至更进一步.
谢谢