多进程读写问题

多进程读写问题

我是这么做的,父进程打开读取文件的句柄,同时也打开要写入目的文件句柄(父子进程共享文件句柄),
每个子进程只读取(文件size/1024/进程数)数据块,
每个子进程用sysseek精确读取文件,问题是::
写的时候就没有办法按照sysseek读取的顺序写入目标文件,有什么好的方法,可以做到这点呢???

#!/usr/bin/perl -w
use strict;
use POSIX;
use constant Max_fork =>6;
$SIG{CHLD}=sub {while((my $child=waitpid(-1,WNOHANG))>0) {}};
my $file=shift;
my $target_file=shift;
my @stat=stat($file);
my $size=$stat[7];
my $average_process_blocks=sprintf("%d",($size/1024/Max_fork));
my $read_fh;
my $write_target;
open($read_fh,$file);
open($write_target,">$target_file");
for(1..Max_fork)
{
      my $pid=fork();
      if($pid==0){
              my $buff;
              for my $i (1..$average_process_blocks){
                        my $offset=1024*($i-1);
                        sysseek($read_fh,$offset,0);
                        sysread($read_fh,$buff,1024);
                        sysseek($write_target,$offset,0); //有问题
                        syswrite($write_target,$buff,1024);//有问题
               }
               exit;
      }
}
my $buff;
my $last_block=$size-$average_process_blocks*Max_fork*1024;
sysseek($read_fh,$average_process_blocks*Max_fork*1024,0);
sysread($read_fh,$buff,$last_block);
sysseek($write_target,$average_process_blocks*Max_fork*1024,0);
syswrite($write_target,$buff,$last_block);
close ($read_fh);
close ($write_target);
问题在于for里面的读写是重复的, 几个进程读和写的是一个内容
恩,是的,
假如子进程读取没有重复,能保证,
一个子进程在写io的时候,syswrite是否是原子呢????
奇怪啊,为什么for循环里要不停的seek呢?

我本以为对于一个fh,只要seek一次就可以了,可是测试下来结果缺不是


大致改了改,但是结果还是不对, 大小对了,但是cksum不一样, 不并发的话cksum就对,今天太忙,先放下,呼唤大牛,大驴....!!!

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl -w
use strict;
use POSIX;
use Fcntl ':flock';
use constant Max_fork =>6;
$SIG{CHLD}=sub {while((my $child=waitpid(-1,WNOHANG))>0) {}};
my $file=shift;
my $target_file=shift;
my @stat=stat($file);
$|++;
my $size=$stat[7];
my $average_process_blocks=sprintf("%d",($size/1024/Max_fork));
print "\$size = $size , \$average_process_blocks = $average_process_blocks\n";

my $read_fh;
my $write_target;
open($read_fh,"<$file");
open($write_target,">$target_file");
for(1..Max_fork)
{
    my $child = $_;
    my $pid=fork();
    if($pid==0){
        my $buff;
        my $offset = 1024 * ($child - 1) * $average_process_blocks;
#       my $ret1 = sysseek($read_fh, $offset, 0 );
#       my $ret2 = sysseek($write_target, $offset, 0);
        my $ret1=0; my $ret2 =0;
        for my $i (1..$average_process_blocks){
            sysseek($read_fh, $offset + 1024 *($i - 1), 0);
            sysread($read_fh,$buff,1024);

            sysseek($write_target, $offset + 1024 *($i - 1), 0);
            syswrite($write_target,$buff,1024);
        }
        my $ret3 = sysseek($write_target, 0, 1);
        close $read_fh;
        close $write_target;

        exit;
    }####else{wait}
}

for (1..6) {wait;}
my $buff;
my $last_block=$size-$average_process_blocks*Max_fork*1024;
sysseek($read_fh,$average_process_blocks*Max_fork*1024,0);
sysread($read_fh,$buff,$last_block);
sysseek($write_target,$average_process_blocks*Max_fork*1024,0);
syswrite($write_target,$buff,$last_block);
close ($read_fh);
close ($write_target);



QUOTE:
原帖由 027xiatian 于 2007-12-14 12:27 发表
恩,是的,
假如子进程读取没有重复,能保证,
一个子进程在写io的时候,syswrite是否是原子呢????

是的.
至少你每次write的那块buffer不会被别的进程强x.
恩,我也改了下,改这一句就ok:
my $offset=1024*($i-1)+($block-1)*1024*$average_process_blocks;

大小都对,
但我感觉还是有问题


QUOTE:
原帖由 dajun 于 2007-12-14 13:50 发表
奇怪啊,为什么for循环里要不停的seek呢?

我本以为对于一个fh,只要seek一次就可以了,可是测试下来结果缺不是


大致改了改,但是结果还是不对, 大小对了,但是cksum不一样, 不并发的话cksum就对,今天太忙,先 ...

在for循环sysseek,是因为每个子进程分别去读文件的不同部分,当然要syseek定位了,读出来的位置和写的位置一样,所以在读完后就立即写到文件,