문제

구체적으로, 과제가 그 자체에 대한 참조를 얻을 수있는 방법이 있습니까?

예를 들어:

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
    pointerToTask : someTaskAccessor;
begin
    pointerToTask = this;
end someTask;
도움이 되었습니까?

해결책

내가 제안 할 수있는 가장 분명한 해결책은 작업의 시작 부분에 Rendez-Vous (항목)를 선언하는 것입니다. 다른 가능성은 작업 유형에 대한 판별제를 사용하는 것인데, 그 역할은 새로운 작업이 위치한 위치를 알려주는 것입니다 (새로운 작업에 대한 액세스를 판별 자로 전달하십시오). 불행히도, 나는 ADA 컴파일러가 없어서 작업 예제를 제공 할 수 없습니다.

어쨌든, 귀하의 의견을 바탕으로 : 새로운 작업의 생성은 어딘가에 처리해야하며,이 시점 에서이 새로운 작업이 이중으로 연결된 목록으로 어디로 들어갈지 결정해야합니다 (최소한 하나의 기존 작업을 알아야합니다. 그들이 의사 소통하기 위해 새로운 것을 만들 때 : 그들은 마술처럼 자신을 발견하지 못할 것입니다). 새로 생성 된 작업과 왼쪽과 오른쪽 동료가있을 때이 순간을 활용하여 이웃 인 모든 사람에게 (다시 한 번 랑데 즈를 사용하여) 알 수 있습니다.

다른 팁

패키지 ada.task_identification current_task 함수를 제공하여 현재 task의 task_id를 검색합니다.

여기 몇 가지.

우선, Ada는 C ++를 다르게 수행합니다. 언어에는 "이"포인터가 없습니다. 파견은 매개 변수에서 수행됩니다. 이것에 대한 한 가지 의미는 C ++와 달리 둘 이상의 매개 변수에서 파견 할 수 있다는 것입니다. 그것은 또 다른 시간에 대한 또 다른 토론입니다. 마음에 들지 않으면 언제든지 파견 매개 변수의 이름을 "this"할 수 있습니다.

둘째, OO 개념은 실제로 작업과 같은 동시성 객체에 적용되지 않습니다. 이것은 Ada의 잘못이 아닙니다. 잘 알려진 문제입니다. 안타깝게도, 그것은 "동시성 문제"라는 상상력으로 다소 상상력이 있었으므로 Google 검색의 프로그래밍 문제로 인해 참조가 휩쓸 렸습니다. 기본 요점은 객체가 내유와 동적 파견 및 모든 좋은 것들을 지원하거나 동시성을 지원할 수 있다는 것입니다. 같은 언어 구조에서 둘 다하는 것은 매우 어렵습니다.

실용성의 문제로, 자신의 과제에 대한 포인터가 필요한 경우, 전역으로 만들거나 어떤 종류의 시작 랑단을 사용하여 포인터를 전달하는 작업을 할 수 있습니다. 나는 이전 에이 작업을 수행 한 것을 보았습니다. 작업자 작업의 스택에 작업이 완료되면 "유휴"스택에 다시 시작했습니다.

이 주제는 오래 되었음에도 불구하고 나는 나 자신과 비슷한 것을 찾고 있었지만 (내 필요는 모든 작업이 액세스 할 수있는 보호 된 해시 맵 저장 영역으로 핸들을 전달할 수있게되었다) 등록에 영향을 미쳤다).

ADA 2005에서는이 작업을 수행 할 수 있습니다. 액세스 점검을 비활성화하기 때문에 권장되지 않는다고 생각했지만 작업을 생성하는 유일한 방법입니다. Task_id를 전달하여 종료 또는 IS_CALLABLE을 확인하기 위해 전달) :

task type someTask; 
type someTaskAccessor is access someTask;

task body someTask is
   -- Initialize the access type variable as pointing to the same task it's declared in.
   pointerToTask : someTaskAccessor := someTask'Unchecked_Access; --equiv to "this" ptr
begin
 --  pointerToTask = this; --this is unneeded, pointerToTask is already set!
end someTask;

내가 당신이라면 당신의 코드를 재구성 할 것입니다. 따라서 다른 작업과 상호 작용하는 몇 가지 작업이 있습니다. 이제 2 개의 작업이 있습니다. 작업을 저장하고 작업의 삽입/삭제를 관리하는 링크 된 목록이 있습니다. 동기화 된 전역 객체입니다.

그렇기 때문에 보호 된 객체를 만들고 그 안에 작업 목록을 저장하도록 조언합니다. 보호 된 것은 일반적으로 수동 객체에 사용되며 일부 리소스는 동기화되어야합니다. 삽입, 제거 등과 같은 절차를 가질 수 있습니다. 이렇게하면 한 번에 하나의 생성 및 제거 만 실행되며 링크 된 목록은 일관되지 않습니다.

각 작업은 작업을 삽입하거나 제거 할 때 변경 될 수있는 "파트너"작업임을 알아야합니다. 나는 이웃을 업데이트 할 작업에 대한 항목을 조언한다. 작업이 오거나 떠날 때 보호 된 물체는 이웃을 업데이트합니다.

이 경우 보호 된 객체가 모든 것을 구성하기 때문에 "이"포인터에 액세스 할 필요가 없습니다. ID 만 필요하므로 작업을 식별 할 수 있습니다 (제거).

코드를 작성하려고하지만 지금은 컴파일러가 없습니다.

task type computer;
type computer_ptr is access all computer;    
task type computer is
 entry init(id:integer);
 entry set_neighbor(left,right:computer_ptr);
end computer;

protected comp_list is
 procedure insert; -- called by organizer
 procedure remove(from:integer); -- called by task
private
 type comp_list is array(integer range<>) of computer_ptr;
 comps:comp_list(1..MAX):=(others=>null); -- or use own structure
end comp_list;

task body computer is
 id_:integer;
 left_n,right_n:computer_ptr:=null;
begin
 accept init(id:integer) do
  id_:=id;
 end init;
 while true loop
  select
   accept set_neighbor(left,right:computer_ptr) do
    left_n:=left;right_n:=right;
   end set_neighbor;
   or
    -- do its work
  end select;
  if (some_condition) then
   comp_list.remove(id_);
   break;
  end if;
 end loop;
end task computer;

protected body comp_list is
 procedure insert is
  p:computer_ptr;
 begin
  p:=new computer;
  -- add to list -> nr;
  p.all.init(nr);
  -- call set_neighbor to its left and itself
 end insert;
 procedure remove(from: integer) is
 begin
  -- remove from list and get its neighbors
  -- call set_neighbor regarding new ones
 end remove;
end comp_list;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top