简体   繁体   English

父线程什么时候同步一个非全局scope的ada任务类型变量?

[英]When does the parent thread synchronize with an ada task type variable with a non-global scope?

I was working on some multithreaded Ada.network code, which involved accepting and handling multiple connections in parallel.我正在处理一些多线程 Ada.network 代码,其中涉及并行接受和处理多个连接。 An ideal situation for the use of Ada tasks, no?使用 Ada 任务的理想情况,不是吗? Specifically, multiple task type variables, started in a loop.具体来说,多个任务类型变量,在一个循环中开始。

Well, I did something like this:好吧,我做了这样的事情:

with Ada.Text_IO;
use Ada.Text_IO;

Procedure foo is
   task type handler is
      entry Start(I: Integer);
   end handler;
   
   task body handler is
      task_index: Integer;
   begin
      accept Start(I: Integer) do
         task_index:=I;
      end Start;
      for I in 1..5 loop
         Put_Line("Task "&task_index'Image&": "&I'Image);
      end loop;
   end handler;

begin -- foo

   for t in 1..5 loop
      declare
         bar: handler;
      begin
         bar.Start(t);
      end;
   end loop;
end foo;

Expecting that the tasks, once they accepted the start entry, would execute in parallel.期望任务一旦接受start条目,就会并行执行。 However, as in this example, the main task waited for each task to finish executing in turn:但是,如本例所示,主任务依次等待每个任务执行完毕:

$ gnat make foo
$ ./foo
Task  1:  1
Task  1:  2
Task  1:  3
Task  1:  4
Task  1:  5
Task  2:  1
Task  2:  2
Task  2:  3
Task  2:  4
Task  2:  5
Task  3:  1
Task  3:  2
Task  3:  3
Task  3:  4
Task  3:  5
Task  4:  1
Task  4:  2
Task  4:  3
Task  4:  4
Task  4:  5
Task  5:  1
Task  5:  2
Task  5:  3
Task  5:  4
Task  5:  5

Declaring all the tasks up-front, in an array fixed the issue, but left me curious about how this is actually working, why, and where this would be documented.预先声明所有任务,在一个数组中解决了这个问题,但让我很好奇这实际上是如何工作的,为什么,以及在哪里记录。

ARM2012 section 9.2 paragraph 6/3 seems to me to say that the main thread waits at the end of execution for it's child tasks to finish, but in practice it seems to be waiting when the tasks leave the current scope before continuing execution (ie looping around, and starting the next task). ARM2012 第 9.2 节第 6/3 段在我看来是说主线程在执行结束时等待它的子任务完成,但实际上它似乎在任务离开当前 scope 继续执行之前等待(即循环周围,并开始下一个任务)。

Is this a compiler issue, a documentation issue, or a coding issue?这是编译器问题、文档问题还是编码问题?

The program (both versions) is working as the Ada standard says.该程序(两个版本)都按照 Ada 标准所说的那样工作。 In the version you show, the task object bar, being declared locally in the declare.. begin.. end block, depends on that block (which is a "master" of the task), and so that block statement waits for the task to terminate before execution proceeds (leaves the block statement).在您显示的版本中,任务 object bar 在 declare..begin..end 块中本地声明,取决于该块(它是任务的“主”),因此该块语句等待任务在执行继续之前终止(离开块语句)。

The part of the RM that defines this is section 9.3, "Task Dependence - Termination of Tasks", http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-9-3.html , which shows an example that is close to your code.定义它的 RM 部分是第 9.3 节,“任务依赖性 - 任务终止”, http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-9-3.html ,它显示了一个示例接近你的代码。 I don't think paragraph 6/3 in section 9.2 is relevant - it describes some rather special cases in which a locally created task is never activated.我不认为第 9.2 节中的第 6/3 段是相关的——它描述了一些相当特殊的情况,在这些情况下,本地创建的任务永远不会被激活。

The solution, as you found, is to declare the task objects globally, so that the "master" lives longer.正如您所发现的,解决方案是全局声明任务对象,以便“主人”寿命更长。 The example in section 9.3 shows another solution that uses access types and dynamically allocated task objects. 9.3 节中的示例显示了另一种使用访问类型和动态分配的任务对象的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM