Uruchomienie równoległych zadań

I. Wywołanie funkcji żółwia. Jest to naturalna składnia dla programowania obiektowego. W języku POOL funkcja wywołana w odniesienu do innego żółwia zostanie umieszczona w jego kolejce zadań i wykonana równolegle, a wynik zostanie przekazany z powrotem do żółwia wywołującego funkcję.
Wykonanie programu żółwia wywołującego funkcję zostanie wstrzymane przy pierwszej próbie użycia wyniku funkcji, jeśli wykonanie funkcji przez równoległego żółwia nie zostało jeszcze zakończone (odroczone odczytanie wyniku).
Typowe sytuacje:
    - żółw, który ma wykonać funkcję jest dostępny poprzez zmienną lub nazwę;
    - funkcja jest uruchamiana na jednym żółwiu dla każdego wywołania (argumenty mogą być różne dla kolejnych wywołań);
    - funkcja zwraca wynik używany przez wywołującego żółwia.

Przykład 1:
Program rysuje koncentryczne koła wykonując w pętli funkcję draw_circle - wariant a), pojedynczy żółw. Ten sam program może też zostać wykonany przez wiele żółwi jednocześnie wykonujących funkcję draw_circle - wariant b).
Opóźnienie w wewnętrznej pętli funkcji pozwala zaobserwować różnicę w wykonaniu programu.

to draw_circle :h :dx [:dt 5]
  seth :h
  repeat 5 [
    repeat 180 [
      fd :dx rt 2
      sync :dt ;opóźnienie
    ]
    "dx *= 0.8
  ]
end

"n := 7

;a) jeden żółw:
;for [i 1 :n] [draw_circle 360 * :i / :n 3]

;b) równoległe żółwie:
"ts := (newturtles :n)
ht
foreach "t :ts [(draw_circle 360 * repcount / :n 3) @ :t]

Rezultat wykonania: grafika, brak wyjścia tekstowego.

II. Obsługa sygnału. Sygnały w języku POOL służą do synchronizacji wykonania zadań przez wiele żółwi. Jeśli w czasie nadejścia sygnału żółw posiada aktywną funkcję obsługi, wykonanie funkcji jest ustawiane w kolejce zadań żółwia i wykonywane równolegle z działaniem innych żółwi.
Typowe sytuacje:
    - funkcja jest uruchamiana na wielu żółwiach jednocześnie;
    - żółw zgłaszający sygnał nie musi być mieć dostępu do żółwi wykonujących obsługę;
    - wynik funkcji nie jest używany przez wywołującego żółwia.

Przykład 2:
Funkcja draw_circle z przykładu 1 została zastąpiona funkcją obsługi sygnału: onsignalgo.

to parallel :h :dx [:dt 5]
  to onsignalgo
    repeat 5 [
      repeat 180 [fd :dx rt 2 sync :dt]
      "dx *= 0.8
    ]
  end
  seth :h
end

"n := 7
repeat :n ["t := (newt $parallel 360 * repcount / :n 3)]
signal "go
ht

Rezultat wykonania: grafika jak w przykładzie 1, brak wyjścia tekstowego.

III. Obsługa zdarzenia. Zdarzenie, podobnie jak sygnał, powoduje dodanie wykonania funkcji obsługi do kolejek zadań wszystkich żółwi, których dotyczy dane zdarzenie i które posiadają aktywną funkcję obsługi tego zdarzenia.
Typowe sytuacje:
    - funkcja jest uruchamiana przez zdarzenie - jego źródłem może być m.in. żółw lub element interfejsu;
    - funkcja jest uruchamiana na wielu żółwiach jednocześnie;
    - funkcja nie zwraca wyniku.

Przykład 3:
Funkcja draw_circle z przykładu 1 została zastąpiona funkcją obsługi zdarzenia: onmouseclick. Aby uruchomić rysowanie, należy kliknąć w żółwie.

to parallel :h :dx [:dt 5]
  to onmouseclick :mousepos
    if distance :mousepos < radius [
      repeat 5 [
        repeat 180 [fd :dx rt 2 sync :dt]
        "dx *= 0.8
      ]
    ]
  end
  seth :h
end

"n := 7
repeat :n ["t := (newt $parallel 360 * repcount / :n 3)]
ht

Rezultat wykonania: grafika jak w przykładzie 1, brak wyjścia tekstowego.

Zobacz także:

Obsługa zdarzeń i sygnałów

@ (dostęp do składowych)

Spis treści