2016-04-12 7 views
0

Я пытаюсь выполнить все процедуры, хранящиеся в массиве, одновременно, но безуспешно. Я могу выполнить их последовательно:Ada одновременное выполнение массива указателей процедур

with ada.text_io; -- Tell compiler to use i/o library 
use ada.text_io; -- Use library routines w/o fully qualified names 

with Ada.Numerics.Float_Random; -- Use numerics for the random generation 
use ada.Numerics.Float_Random; 

procedure Main is 

    type Callback_Procedure is access procedure; -- Type that contains a procedure pointer 
    type arr is array (Natural range <>) of Callback_Procedure; -- Array starting from 0 toi infinite of procedure pointers 
    seed : Generator; -- Seed for the generator 

    -- Procedure that will execute "concurrently" the procedures passed in the array 
    procedure EjecutarConcurrentemente(procs : in arr) is 
    begin 

     for index in 0 .. procs'Last loop 

     procs(index).all; -- .all dereferences the pointer so it is the procedure itself (the value pointed by the pointer) 

     end loop;  

    end EjecutarConcurrentemente; 

    function rndDelay return Duration is 
     num : Duration; 
    begin 
     num := Duration(Random(seed)); 
     return num * Duration(10); 
    end ; 


    procedure test0 is 
    begin 
     delay rndDelay; 
     put("test0"); 
     New_Line; 
    end test0; 

    procedure test1 is 
    begin 
     delay rndDelay; 
     put("test1"); 
     New_Line; 
    end test1; 

    procedure test2 is 
    begin 
     delay rndDelay; 
     put("test2"); 
     New_Line; 
    end test2; 

    procedure test3 is 
    begin 
     delay rndDelay; 
     put("test3"); 
     New_Line; 
    end test3; 

    procedure test4 is 
    begin 
     delay rndDelay; 
     put("test4"); 
     New_Line; 
    end test4; 

    procedure test5 is 
    begin 
     delay rndDelay; 
     put("test5"); 
     New_Line; 
    end test5; 

    procs : arr(0..5); 

begin 

    Reset(seed); 

    procs(0) := test0'Access; 
    procs(1) := test1'Access; 
    procs(2) := test2'Access; 
    procs(3) := test3'Access; 
    procs(4) := test4'Access; 
    procs(5) := test5'Access; 

    EjecutarConcurrentemente(procs); 

end Main; 

Главное тело процедуры заполнит массив с 6 процедур, объявленных до и вызовы EjecutarConcurrentemente с этого массива, и она должна быть эта новая процедура, который должен выполнить процедуры массива одновременно.

Мне сказали использовать функциональные возможности Task, и testX должен быть процедурами без аргументов.

Надеюсь, я объяснил это хорошо, также я только что начал с Ada, поэтому код, скорее всего, будет плохо сформирован.

Спасибо.

+0

Почему количество аргументов в процедурах testX предотвращает использование задач? – egilhh

+0

«Одновременно» с чем? Главная программа? (Легко-иш), друг друга? (Трудная). –

+0

@egilhh Я не говорю это, я просто говорю, что это реквизит –

ответ

1

Вот код прекрасно работает:

with ada.text_io; -- Tell compiler to use i/o library 
use ada.text_io; -- Use library routines w/o fully qualified names 

with Ada.Numerics.Float_Random; -- Use numerics for the random generation 
use ada.Numerics.Float_Random; 

procedure Main is 

    type Callback_Procedure is access procedure; -- Type that contains a procedure pointer 
    type arr is array (Natural range <>) of Callback_Procedure; -- Array starting from 0 toi infinite of procedure pointers 
    seed : Generator; -- Seed for the generator 

    task type Ex (proc : Callback_Procedure); 
    type A is access Ex; 

    task body Ex is 
    begin 
     proc.all; --.all dereferences the pointer so it is the procedure itself (the value pointed by the pointer) 
    end Ex; 

    -- Procedure that will execute concurrently the procedures passed in the array 
    procedure EjecutarConcurrentemente(procs : in arr) is 
     p : A; 
    begin 

     for index in 0 .. procs'Last loop 

     p := new Ex(procs(index)); 

     end loop;  

    end EjecutarConcurrentemente; 

    function rndDelay return Duration is 
     num : Duration; 
    begin 
     num := Duration(Random(seed)); 
     return num * Duration(10); 
    end ; 


    procedure test0 is 
    begin 
     delay rndDelay; 
     put("test0"); 
     New_Line; 
    end test0; 

    procedure test1 is 
    begin 
     delay rndDelay; 
     put("test1"); 
     New_Line; 
    end test1; 

    procedure test2 is 
    begin 
     delay rndDelay; 
     put("test2"); 
     New_Line; 
    end test2; 

    procedure test3 is 
    begin 
     delay rndDelay; 
     put("test3"); 
     New_Line; 
    end test3; 

    procedure test4 is 
    begin 
     delay rndDelay; 
     put("test4"); 
     New_Line; 
    end test4; 

    procedure test5 is 
    begin 
     delay rndDelay; 
     put("test5"); 
     New_Line; 
    end test5; 

    procs : arr(0..5); 

begin 

    Reset(seed); 

    procs(0) := test0'Access; 
    procs(1) := test1'Access; 
    procs(2) := test2'Access; 
    procs(3) := test3'Access; 
    procs(4) := test4'Access; 
    procs(5) := test5'Access; 

    EjecutarConcurrentemente(procs); 

end Main; 

Я просто сделать задачу с указателем процедуры в качестве параметра, а затем в цикле массива я

new Ex(procs(index)); 

и он мгновенно начинает новый Задача с данной процедурой

2

Тот, кто сказал вам использовать задачи для одновременного выполнения, дал вам правильный ответ. Для одновременного запуска всех шести процедур вам потребуется шесть задач (и шесть процессоров/процессорных ядер).

+0

Я только что понял это. Я не думал о выполнении задачи, чтобы принять указатель на процедуру. Я отвечу кодом. –