获取任务中字段的值

时间:2019-04-28 11:36:05

标签: ada

我正在尝试获取任务中字段的值。 import time import random from selenium import webdriver chromedriver = "C:\\Users\\LORD\\Desktop\\max spam shit\\chromedriver") driver = webdriver.Chrome(chromedriver) 循环非常大,所以我只剩下重要的部分。 基本上,在用户输入“ w”后,我希望控制台打印有关这三个字段的信息。

image

奖金问题:任务正文Worker有一个循环,我想在循环的最后做一个“ FinishedJob ++”;但我也不知道该怎么做。

2 个答案:

答案 0 :(得分:3)

任务不是记录。它不包含可以从任务外部直接访问的字段。 您可以提供任务条目来查询在类中本地声明的变量的当前值,但是请记住,条目会强制对调用任务和被调用任务进行同步。

“奖励问题”的措辞看起来像C或C ++思维。 Ada不是简单的C或C ++,它的开始和结尾都替换了“ {”和“}”。

您希望FinishedJob计数具有什么可见性?您似乎想与其他任务(例如程序主任务)共享该号码。最简单的方法是在工作任务完成时创建一个递增的受保护对象,即外循环,并在适当的时候由读取任务进行读取。

这种受保护对象的可能示例是:

protected Counter is
   procedure Increment;
   entry Read(Num : out Natural);
private
   Tally : Natural := 0;
   Is_Updated : Boolean := False;
end Counter;

protected body Counter is
   procedure Increment is
   begin
      Tally := Tally + 1;
      Is_Updated := True;
   end Increment;

   entry Read(Num : out Natural) when Is_Updated is
   begin
      Num := Tally;
      Is_Updated := False;
   end Read;
end Counter;

编写器在完成其外部循环后调用Counter.Increment。读取器调用Counter.Read并在新值可用后立即获取。

答案 1 :(得分:2)

根据您在屏幕截图中显示的内容,在我看来,您正在寻找一种配置任务/工作人员(Worker_IdPatient(?))的方法,然后任务/工作人员已经启动,可以监视其进度(Jobs_Done)。

假设以上所述,并且考虑到吉姆·罗杰斯(Jim Rogers)已经做出的重要标记,可能很有趣的是,通常通过所谓的任务判别器而不是初始accept条目来配置任务。任务判别 可以从任务外部访问(请参见RM 9.1 (9)),并且根据定义是不变的。因此,根据您的情况,您可以定义两个任务判别式,如

task type T_My_Task
   (Worker_Id : Natural;
    Patient   : Boolean);

可以用作

declare
  T1 : T_My_Task  (1, True);
  T2 : T_My_Task  (2, True);
begin

  Put_Line (T1.Worker_Id'Image);
  Put_Line (T1.Patient'Image);

  Put_Line (T2.Worker_Id'Image);
  Put_Line (T2.Patient'Image);

end;

出于我个人的兴趣,我尝试根据我认为您可以解决此问题的方式来编写一些示例程序。我很确定存在更多方法,并且我不会声称这是最好的方法。我添加了一些评论以澄清我(尝试做的)事情。这可能对您有用。

注意:由于我对初始设计不满意,因此我针对最初发布的内容更新了以下示例。

main.adb (主程序)

with Ada.Text_IO; use Ada.Text_IO;
with Work_Force;  use Work_Force;

procedure Main is

   Worker_Configs : T_Worker_Config_Array :=
     (0 => (Patient => True ),
      1 => (Patient => False),
      2 => (Patient => False),
      3 => (Patient => True ),
      4 => (Patient => False));

   package My_Work_Force is
     new Generic_Work_Force (Worker_Configs);
   use My_Work_Force;

   User_Response : Character;

begin

   Main_Loop: loop

      Put_Line ("--==[ MENU ]==--");
      New_Line;
      Put_Line (" S - Show status workers");
      Put_Line (" Q - Quit");
      New_Line;
      Put (" ==> "); Get (User_Response);
      New_Line;

      case User_Response is

         when 'S' =>

            for Worker_Id in T_Worker_Id'Range loop
               declare
                  Worker_Config : T_Worker_Config :=
                    Get_Worker_Config (Worker_Id);
                  Worker_Status : T_Worker_Status :=
                    Get_Worker_Status (Worker_Id);
               begin
                  Put_Line (" Worker. . . : " & Worker_Id'Image);
                  Put_Line (" Patient . . : " & Worker_Config.Patient'Image);
                  Put_Line (" Jobs_Done . : " & Worker_Status.Jobs_Done'Image);
                  New_Line;
               end;
            end loop;

         when 'Q' =>

            --  The call "Terminate_All_Workers" is actually a request. The
            --  call is non-blocking thanks to the protected object "Manager"
            --  in the "Work_Force" package. The program itself, however,
            --  will not terminate until all tasks have terminated (i.e.
            --  exited the "Worker_Loop" (see task body of "T_Worker").

            My_Work_Force.Terminate_All_Workers;
            Put_Line ("Program will end when all workers have terminated.");
            New_Line;
            exit Main_Loop;

         when others =>

            Put_Line ("(Unknown option)");
            New_Line;

      end case;

   end loop Main_Loop;

end Main;

work_force.ads (程序包规格;暂时无法提供更好的名称)

package Work_Force is

   --  Record type "T_Worker_Config" contains all items required to configure
   --  a worker. For now it contains only 1 item, but this can easily be
   --  extended.

   type T_Worker_Config is
      record
         Patient : Boolean;
      end record;

   type T_Worker_Config_Array is
     array (Natural range <>) of aliased T_Worker_Config;


   --  Record type "T_Worker_Status" contains all items related tot the status
   --  of the worker. As for type "T_Worker_Config", it now contains only 1
   --  item, but this can easily be extended.

   type T_Worker_Status is
      record
         Jobs_Done : Natural;
      end record;


   generic
      Workers_Config : T_Worker_Config_Array;      
   package Generic_Work_Force is

      --  The package "Generic_Work_Force" exposes a restricted set of
      --  subprograms such to have proper interface/implementation decoupling
      --  (and reduce the impact of changes in the implementation, etc.).

      subtype T_Worker_Id is
        Natural range Workers_Config'Range;

      function Get_Worker_Config
        (Worker_Id : T_Worker_Id) return T_Worker_Config;
      --  Gets the configuration from the worker "Worker_Id". A call to
      --  this subprogram is non-blocking.

      --  NOTE: "Get_Worker_Config" is not strictly necessary as the
      --  "Workers_Config" parameter of the generic package can be accessed
      --  directly from outside the package, but it looks nice and symmetric
      --  with respect to the subprogram "Get_Worker_Status" below.

      function Get_Worker_Status
        (Worker_Id : T_Worker_Id) return T_Worker_Status;
      --  Gets the status from the worker "Worker_Id". A call to this
      --  subprogram is non-blocking.

      procedure Terminate_All_Workers;
      --  Request to terminate all workers. A call to this subprogram is
      --  non-blocking.

      --  NOTE: there is no private part in this spec as there are no
      --  private types defined in the public part of the spec. All
      --  implementation details can reside in the body such that they
      --  can change independently from the spec, if necessary, without 
      --  the need to touch the spec file.

   end Generic_Work_Force;

end Work_Force;

work_force.adb (程序包主体)

package body Work_Force is

   package body Generic_Work_Force is

      -------------
      -- Manager --
      -------------

      --  Protected object instance "Manager" is a synchronized 
      --  data object that administrates common requests to all workers.

      protected Manager is

         procedure Request_Termination;
         --  Requests the termination of the workers.
         --  ===> To be called from another task (e.g. the program main task).

         function Is_Termination_Requested return Boolean;
         --  Returns True if the termination is requested.
         --  ===> To be called from a worker task.

      private
         Termination_Requested : Boolean := false;
      end Manager;

      protected body Manager is

         procedure Request_Termination is
         begin
            Termination_Requested := True;
         end Request_Termination;

         function Is_Termination_Requested return Boolean is
         begin
            return Termination_Requested;
         end Is_Termination_Requested;

      end Manager;


      -------------------
      -- T_Worker_Data --
      -------------------

      --  Protected object type "T_Worker_Data" is a synchronized 
      --  data type that administrates dynamic worker data that must
      --  be shared with other tasks.

      protected type T_Worker_Data is      

         procedure Report_Job_Done;
         --  Increments the "Jobs_Done" counter.
         --  ===> To be called from a worker task.

         function Get_Jobs_Done return Natural; 
         --  Returns the value of the "Jobs_Done" counter.
         --  ===> To be called from another task (e.g. the program main task).

      private
         Jobs_Done : Natural := 0;      
      end T_Worker_Data;

      protected body T_Worker_Data is

         ---------------------
         -- Report_Job_Done --
         ---------------------

         procedure Report_Job_Done is
         begin
            Jobs_Done := Jobs_Done + 1;
         end Report_Job_Done;

         -------------------
         -- Get_Jobs_Done --
         -------------------

         function Get_Jobs_Done return Natural is
         begin
            return Jobs_Done;
         end Get_Jobs_Done;

      end T_Worker_Data;


      --------------
      -- T_Worker --
      --------------

      --  Task type "T_Worker" is the actual worker. Note that the worker
      --  configuration, "Workers_Config (Worker_Id)", is visible to the
      --  task as it is a parameter to the generic package.

      task type T_Worker
        (Worker_Id   : T_Worker_Id;
         Worker_Data : access T_Worker_Data); 

      task body T_Worker is

         --  Just to show how to access the worker's configuration.
         Patient : Boolean := Workers_Config (Worker_Id).Patient;
         pragma Unreferenced (Patient);

      begin
         Worker_Loop: loop    

            if Manager.Is_Termination_Requested then
               exit Worker_Loop;
            end if;

            --  Do some work...
            delay (Worker_Id * 0.1 + 0.2);

            --  Maybe check the termination request somewhere half-way (if
            --  that's allowed, it might be that the worker must finish its job).

            if Manager.Is_Termination_Requested then
               exit Worker_Loop;
            end if;

            --  Continue the work...
            delay (Worker_Id * 0.1 + 0.2);

            --  Report job done.
            Worker_Data.Report_Job_Done;

         end loop Worker_Loop;
      end T_Worker;      


      --  Arrays that will hold the instances of "T_Worker" and "T_Worker_Data".
      --  The initialization will be done in the package initialization section
      --  which is executed during the elaboration of the package.
      Workers      : array (T_Worker_Id'Range) of access T_Worker;
      Workers_Data : array (T_Worker_Id'Range) of access T_Worker_Data; 


      -----------------------
      -- Get_Worker_Config --
      -----------------------

      function Get_Worker_Config
        (Worker_Id : T_Worker_Id) return T_Worker_Config
      is
      begin
         return Workers_Config (Worker_Id);
      end Get_Worker_Config;

      -----------------------
      -- Get_Worker_Status --
      -----------------------

      function Get_Worker_Status
        (Worker_Id : T_Worker_Id) return T_Worker_Status 
      is
      begin
         return (Jobs_Done => Workers_Data (Worker_Id).Get_Jobs_Done);
      end Get_Worker_Status;

      ---------------------------
      -- Terminate_All_Workers --
      ---------------------------

      procedure Terminate_All_Workers is
      begin
         Manager.Request_Termination;
      end Terminate_All_Workers;


      -- Start processing for Generic_Work_Force.

   begin

      --  This is the initialization sequence of the package which will be
      --  called during its elaboration.

      for Worker_Id in T_Worker_Id'Range loop

         Workers_Data (Worker_Id) :=
           new T_Worker_Data;

         Workers (Worker_Id) := 
           new T_Worker 
             (Worker_Id   => Worker_Id,
              Worker_Data => Workers_Data (Worker_Id));  

      end loop;

   end Generic_Work_Force;

end Work_Force;