Multithreading 如何将多线程应用于Bio::SeqIO翻译代码(Bioperl)?
我正在用这个代码将一个fasta核苷酸文件翻译成蛋白质序列Multithreading 如何将多线程应用于Bio::SeqIO翻译代码(Bioperl)?,multithreading,perl,bioperl,Multithreading,Perl,Bioperl,我正在用这个代码将一个fasta核苷酸文件翻译成蛋白质序列 use Bio::SeqIO; use Getopt::Long; my ($format,$outfile) = 'fasta'; GetOptions( 'f|format:s' => \$format, 'o|out|outfile:s' => \$outfile, ); my $oformat = 'fasta'; $file=$ARGV[0]; chomp $file; # thi
use Bio::SeqIO;
use Getopt::Long;
my ($format,$outfile) = 'fasta';
GetOptions(
'f|format:s' => \$format,
'o|out|outfile:s' => \$outfile,
);
my $oformat = 'fasta';
$file=$ARGV[0];
chomp $file;
# this implicity uses the <> file stream
my $seqin = Bio::SeqIO->new( -format => $format, -fh => \*ARGV);
my $seqout;
if( $outfile ) {
$seqout = Bio::SeqIO->new( -format => $oformat, -file => ">$outfile" );
} else {
# defaults to writing to STDOUT
$seqout = Bio::SeqIO->new( -format => $oformat );
}
while( (my $seq = $seqin->next_seq()) ) {
my $pseq = $seq->translate();
$seqout->write_seq($pseq);
}
#此WHILE应该是多线程的
while( (my $seq = $seqin->next_seq()) ) {
my $pseq = $seq->translate();
$seqout->write_seq($pseq);
}
sleep 1 if 0.2 > rand;
}
print "Thread done.\n";
return;
}
print "\n$time\n";
my $time = localtime;
print "$time\n";
#此WHILE应该是多线程的
while( (my $seq = $seqin->next_seq()) ) {
my $pseq = $seq->translate();
$seqout->write_seq($pseq);
}
sleep 1 if 0.2 > rand;
}
print "Thread done.\n";
return;
}
print "\n$time\n";
my $time = localtime;
print "$time\n";
正在创建线程,但不知何故它无法处理fasta文件。
第一个代码在没有多线程的情况下运行良好。我恐怕不会为您重写代码,但我可以给您一些如何完成线程的建议 关于perl线程,您需要了解的是它不是一个轻量级线程。您应该生成相当于并行度的线程数量,将它们从
Thread::Queue
中运行,然后从那里开始
您还需要避免使用任何非线程安全的模块-如果小心,您可以使用它们,但这通常意味着在程序开始时使用require
和import
在线程中实例化它们,而不是use
我还建议避免并行执行输出IO—返回线程结果并在“主”线程中合并它们(必要时进行排序)(或派生出单个编写器)
所以我会选择这样的东西
#!/usr/bin/env perl
use strict;
use warnings;
use threads;
use Thread::Queue;
use Storable qw ( freeze thaw );
my $NUM_THREADS = 16; #approx number of cores.
my $translate_q = Thread::Queue->new;
my $translate_results_q = Thread::Queue->new;
sub translate_thread {
while ( my $item = translate_q->dequeue ) {
my $seq = thaw $item;
my $pseq = $seq->translate();
$translate_results_q->enqueue( freeze $pseq );
}
}
threads->create( \&translate_thread ) for 1 .. $NUM_THREADS;
while ( my $seq => $seqin->next_seq ) {
$translate_q->enqueue( freeze($seq) );
}
$translate_q->end;
$_->join for threads->list;
$translate_results_q->end;
while ( my $result = $translate_results_q->dequeue ) {
my $pseg = thaw($result);
}
注意-这不会按原样工作,因为它缺少与ocde其余部分的合并。但希望它能说明队列和线程如何工作以获得并行性
您可以使用Storable中的冻结
和解冻
传递对象,并使用并行性将其解包
不要在线程数量上太过疯狂-对于主要的计算工作负载(例如没有IO),那么线程数量等于核心数量就差不多了。如果他们在IO上阻塞,你可以增加这个数字,但超过大约两倍不会有多大作用
你不可能真正有效地并行磁盘IO,它就是不能那样工作。所以在“主”线程中这样做 谢谢,这是一个很好的建议@Sobrique。我将尝试使它与剩余的代码一起工作。