我正在尝试获取任务中字段的值。 import time
import random
from selenium import webdriver
chromedriver = "C:\\Users\\LORD\\Desktop\\max spam shit\\chromedriver")
driver = webdriver.Chrome(chromedriver)
循环非常大,所以我只剩下重要的部分。
基本上,在用户输入“ w”后,我希望控制台打印有关这三个字段的信息。
奖金问题:任务正文Worker
有一个循环,我想在循环的最后做一个“ FinishedJob ++”;但我也不知道该怎么做。
答案 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_Id
,Patient
(?))的方法,然后任务/工作人员已经启动,可以监视其进度(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;