Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Perl TK Gui冻结_Multithreading_Perl_User Interface - Fatal编程技术网

Multithreading Perl TK Gui冻结

Multithreading Perl TK Gui冻结,multithreading,perl,user-interface,Multithreading,Perl,User Interface,我有一个perl tk应用程序,在其中我创建了许多对象,并用对象中的信息更新perl tk gui显示。我需要在gui的树中添加大量作业(比如30k)。如果我一次性添加所有作业,gui将冻结 下面是代码片段: sub Importjobs { #================= start creation of objects============================= my JobList $self = shift; my $exportedJobList =

我有一个perl tk应用程序,在其中我创建了许多对象,并用对象中的信息更新perl tk gui显示。我需要在gui的树中添加大量作业(比如30k)。如果我一次性添加所有作业,gui将冻结

下面是代码片段:

sub Importjobs
{

  #================= start creation of objects=============================
  my JobList $self = shift;
  my $exportedJobList = shift;
  # third parameter whether to clear the list
  $self->clear () unless shift;
  my $noOfProcsToBeAdded = shift || 3000;



 my $cellCollection = Tasks::CellCollection::instance ();
  my $calcActionsPathHash = $cellCollection->caPathCAHash ();
  my $collectionCellNames = $cellCollection->allCellNames ();

  my @importedJobs = ();
  # if the given job list is empty, add import job list to it
  push @{$self->_importJobList()}, @$exportedJobList;
  $exportedJobList = [];
  # do not import new jobs if the previous jobs are still being created
  foreach my $taskGenJob(@{$self->getTaskGenJobObjs()}) {
    goto FINISH if TaskGenJobState::CREATE == $taskGenJob->state();
  }
  # now get each job and add it into the imported jobs till the noOfJobs exceeds $noOfJobsToBeAdded
  while(my $jobDescription = shift @{$self->_importJobList()}) {
    my $taskInstantiation = $jobDescription->{'taskInstantiation'};
    my $caPath     = $taskInstantiation->{'calcActionPath'};
    my $errMsgPrefix = 'Error importing ' . join ('-', $task, $command, $method, $caPath);
    my @calcActionList;
    if(defined $caPath) {
      my $calcAction = $calcActionsPathHash->{ $caPath };
      unless($calcAction) {
        my $errMsg = $errMsgPrefix . ": the calcAction is not defined within the current CellCollection : " . $caPath;
        $logger4Perl -> error ($errMsg);
        next;
      }
      push @calcActionList, $calcAction;
    } else {
      my @mList;
      if(not defined $method) {
        push @mList, @{$task->getMethods(cellCollection => $cellCollection, command => $command)};
        $method = join(' ', @mList);
      } elsif($method eq $task_desc::default_method) {
        @mList = ($task_desc::default_method);
      } else {
        @mList = sort (grep { $_ } split(/\s+|__/, $method));
      }
      foreach my $m (@mList) {
        push(@calcActionList,  @{$cellCollection->findCalcActions($task, $command, $m)});
      }
    }
    foreach my $calcAction(@calcActionList) {
       my TaskGenJob $job = TaskGenJob->new ();
      $logger4Perl->info ("Adding $caPath");
      push (@importedJobs, $job);
      my $noOfProcsBeingAdded = $job->calculateNoOfJobExecObjs();
      $noOfProcsToBeAdded -= $noOfProcsBeingAdded;
    }
    last if 1 > $noOfProcsToBeAdded;
  }
  #================= End creation of objects=============================

  #Below function updates the GUI display
    $self->addJobs (\@importedJobs);  

  #================= Mechanism which am using so that GUI will be active after certain time limit=============================
  FINISH:
  if(@{$self->_importJobList()}) {
    $self->parentDlg()->parentWnd()->after(60000,
      sub {
        $GuiTasksAppl::mainDlg->Disable();
        $self->importJobList([], 'noclear', 200);
        $GuiTasksAppl::mainDlg->Enable();
      });
  }
}
目前我的做法是使用$noofprocstobeaded变量添加3000个作业,并保持空闲一段时间,然后在一段时间后重复该过程。在这个空闲过程中,有不同的过程在GUI中处理作业

有人能提出比这更好的方法吗??? 期待关于线程、共享内存的想法。

首先,如果GUI在30k大更新期间冻结(并且从未解冻),那么您可能已经发现了Tk错误,因为这不应该发生。然而,如果它仅仅在一段时间内没有响应,那么减轻延迟是有意义的

在过去,我使用Tk::repeat()或Tk::after()来驱动UI更新例程。用户界面通常不需要以很高的速度更新,因此每隔几百毫秒可能是一个合理的延迟。决定因素在很大程度上取决于您需要的接口的响应程度。然后在作业导入步骤中:将引用附加到UI更新例程的列表中,然后定期调用$MW->update()。更新例程不一定需要在每次调用期间处理完整列表,但您不希望处理过程落后太多

我还建议使用一些视觉指示器来确定更新是否仍在进行中


如果ImportJobs在计算上很昂贵,那么显然可以执行多进程/多线程技巧来利用系统上的多个处理器。但这将增加一点复杂性和测试工作

在添加作业时,您能否
$mw->更新
$mw->idletasks
?请参见以下说明: