我是 perl 线程的新手。
我有一个包含项目列表的文件(每个项目都在一个单独的行中),我想并行构建这些项目。目前,每个线程:
- 以“读取”模式打开文件
- 保存一些项目的列表(= 一些文件行)
- 关闭文件
- 再次打开文件 - 作为“写入”模式
- 在没有选择的行的情况下重写它
为了确保每个线程是唯一访问文件的线程,我尝试使用信号量。
由于某种原因,发生了线程冲突,我无法弄清楚我做错了什么。
我可以看到(在我的“报告”中,它还获取每个构建的当前时间)不同的线程从“共享”文件中选择相同的项目(它只偶尔发生一次,但仍然......)
我什至不确定我的 $semaphore decleration 作为“我的”变量是否合法。
任何帮助将不胜感激!
谢谢。
这是我的代码的一部分:
my $semaphore = Thread::semaphore->new() ;
sub build_from_targets_list{
#...
open(REPORT, "+>$REPORT_tmp"); # Open for output
#....
@threads =();
for ($i = 0; $i < $number_of_cores; $i++){
my $thr = threads->new(\&compile_process, $i,*REPORT);
push @threads, $thr;
}
$_->join for @threads;
close (REPORT);
}
### Some stuff..
sub compile_process{
*REPORT = shift(@_);
#...
while (1){
$semaphore->down();
open (DATA_FILE, $shared_file);
flock(DATA_FILE, 2);
while ($record = <DATA_FILE>) {
chomp($record);
push(@temp_target_list,$record);
}
# ... choose some lines (=projects)...
# remove the projects that should be built by this thread:
for ($k = 0; $k < $num_of_targets_in_project; $k++){
shift(@temp_target_list);
}
close(DATA_FILE);
open (REWRITE,">$shared_file");
flock(REWRITE, 2);
seek(REWRITE, 0, 0);
foreach $temp_target (@temp_target_list){
print REWRITE "$temp_target\n";
}
close (REWRITE);
## ... BUILD selected projects...
$semaphore->up();
}
}