Tworzenie tasków w Delphi

0

Witam,
W moim programie zacząłem używać tasków. Niestety okazało się że czasem niektóre taski nie są wykonywane. Poniżej fragmenty kodu. Nie wiem czy ja robię gdzieś błąd, czy to wina kompilatora (Delphi 10.3 Community Edition). Dodam, iż bez jakiejkolwiek zmiany kodu, po kolejnej kompilacji okazuje się że inne taski nie zostały wykonane, bywają też kompilacje, gdzie wszystkie taski zostaną wykonane.

var task:array of ITask;
    B1,B2:TBitmap;
begin
   SetLength(task,5);
   B1:=TBitmap.Create;
   B2:=TBitmap.Create;
   task[0]:=TTask.Create(procedure()
   begin
       .....
   end);
   task[0].Start;
   task[1]:=TTask.Create(procedure()
   begin
       .....
   end);
   task[1].Start;
   task[0].Wait();
   task[1].Wait();
   task[2]:=TTask.Create(procedure()
   begin
       .....
   end);
   task[2].Start;
   task[3]:=TTask.Create(procedure()
   begin
       .....
   end);
   task[3].Start;
   task[2].Wait();
   task[3].Wait();
   task[4]:=TTask.Create(procedure()begin
       .....
   end);
   task[4].Start;
   .....
   task[4].Wait();
   .....
   B1.Free;
   B2.Free;
end;

Podzielone jest to na etapy, gdzie poszczególne taski mogą działać równorzędnie, sam kod bez uruchamiania tasków działa bezbłędnie. W poszczególnych taskach są obrabiane bitmapy. Zainstalowałem też Lazarusa, lecz nie ogarniam go, nie mogę użyć B1:=TBitmap.Create; ani B1.Free, otrzymuję "Error: identifier idents no member "Create" ". Wracając do delphi zmieniałem

  task[x].Wait();

na

   if task[x].Status=TTaskStatus(2) then task[x].Wait();

lecz nie zmieniło to nic w działaniu.

0

słuchaj, ale po co są te Wait po drodze? Wg mnie powinieneś na koniec tej procedury po prostu dać WaitForAll i to wszystko. System operacyjny niech się zajmie wykonaniem tych wszystkich operacji w sposób jak najbardziej równoległy a ty tylko masz poczekać na ich efekt? Taski to jednak nie do końca wątki gdzie często należy sterować ich wykonywaniem. Tutaj wrzucasz wszystko do wora i czekasz na wynik.

0

Program musi czekać na wyniki tasków, ponieważ w dalszym etapie są one wykorzystywane. Równocześnie z głównym wątkiem programu mogą działać jedynie task 0 i 1, później można dopiero ruszyć gdy 0 i 1 się zakończą. Wtedy można uruchomić task 2 i 3, a gdy te się zakończą można uruchomić 4. Program leci kawałek dalej, dopóki nie potrzebuje wyniku 4.
Wcześniej było to w jednym ciągu, lecz na kompie i7 4Ghz trwa to 10 sekund obciążając procesor tyko w 10%. Dlatego chcę rozbić to na kilka wątków.

0

hmm, aż tak dużego przyrostu szybkości raczej nie będzie bo niestety twoja procedura musi się w zasadzie wykonywać szeregowo. Równolegle pójdzie task 0 i 1 a później 2 i 3. Niby powinno być lepiej ale na pewno nie o tyle ile wychodzi z czystej matematyki. Dodatkowo zyskasz to że program ci się nie zamrozi w trakcie startu ale i tak będzie nie do używania.

Wracając jednak do twojego pytania, wg Embarcadero metoda Wait czeka tak długo aż task się wykona lub upłynie limit czasu. Niestety nigdzie nic nie mogę znaleźć o tym limicie czasu. Być może jest to twój problem, zbyt długo trwa to obliczanie i trzeba podnieść limit czasu?

0

Nie podawałem czasu, jaki ma czekać, po prostu dawałem Wait(), lecz czasem niektóre wątki się nie wykonywały, najczęściej brakowało nałożonych bitmap, lecz czasem były nałożone całkowicie inne bitmapy, jakby powstawały przecieki pamięci. Potem dawałem if task[x].Status=TTaskStatus(2) then task[x].Wait(); lecz czas wykonania takich procedur był kilkukrotnie dłuższy niż bez tasków, czasem po minucie oczekiwania zamykałem program Ctrl+F2. Poszczególne taski przetwarzają bardzo dużą ilość danych, nawet uruchomienie dwóch tasków + główny wątek dałoby duże przyspieszenie. Bywało przy niektórych kompilacjach, że wszystkie taski zadziałały i wtedy obciążenie procesora wzrastało do 60% a czas skracał się o połowę. Oczywiście nie mogę polegać na losowym działaniu, i dopiero po wydruku orientować się że tym razem było dobrze lub źle, podgląd wydruku używam, lecz czasem mogę nie zwrócić uwagi na pewne detale, wobec tego teraz używam programu bez tasków, lecz chciałbym wiedzieć co robiłem źle.

1 użytkowników online, w tym zalogowanych: 0, gości: 1