Dynamiczne tworzenie równoległych wątków

Dynamiczne tworzenie równoległych wątków
AS
  • Rejestracja:około 8 lat
  • Ostatnio:9 miesięcy
  • Postów:48
2

Ja jak potrzebuję wątków to idę po prostu po najmniejszel lini oporu i robię to tak.
Najpierw odpalam wątek ,który robi za kierownika (uruchamia pracowników i czeka aż skończą pracę). Celowo używam najpierw wątka kierownika aby nie blokować głównego watku aplikacji.

Kopiuj
type
  TSupervisorThread = class(TThread)
  private
    { Private declarations }
    CopiedProgress:integer;
  protected
    procedure Execute; override;
  end;

type
  TWorkerThread = class(TThread)
  private
    { Private declarations }
    ThreadIndex:integer;  
  protected
    procedure Execute; override;
  end;

var Progress:integer;

procedure TSupervisorThread.Execute;
var x:integer;
    WaitStatus,Threads:cardinal;
    WorkerThreadArray:array of TWorkerThread;
    WorkerThreadHandleArray:array of THandle;
begin

 Threads:=16; //np. 16 wątków 

  SetLength(WorkerThreadArray,Threads);
  SetLength(WorkerThreadHandleArray,Threads);
  
   for x:=0 to Threads-1 do
  begin
   
    WorkerThreadArray[x]:=TWorkerThread.Create(True);
    WorkerThreadHandleArray[x]:=WorkerThreadArray[x].Handle;
    WorkerThreadArray[x].FreeOnTerminate:=false;
    WorkerThreadArray[x].Priority:=tpNormal;
    WorkerThreadArray[x].ThreadIndex:=x;
    WorkerThreadArray[x].Resume;

  end;

  repeat
    WaitStatus:=WaitForMultipleObjects(Threads, @WorkerThreadHandleArray[0], True, 100);
    Synchronize(GetProgress);
    if Terminated=true then for x:=0 to Threads-1 do 
begin
    WorkerThreadArray[x].Terminate;
    if WorkerThreadArray[x].Suspended=true then WorkerThreadArray[x].Resume;
end;

  until WaitStatus<>WAIT_TIMEOUT;

  for x:=0 to Threads-1 do if Assigned(WorkerThreadArray[x])=true then FreeAndNil(WorkerThreadArray[x]);
  

end;

procedure TSupervisorThread.GetProgress;
begin
     CopiedProgress:=Progress; // albo pokazać gdzieś w GUI 
end;

procedure TWorkerThread.Execute;
begin
     {jakaś praca tutaj}
    Synchronize(UpdateProgress)
     
end;

procedure TWorkerThread.UpdateProgress;
begin
     Inc(Progress);
end;

edytowany 2x, ostatnio: flowCRANE
flowCRANE
Mówi się po linii najmniejszego oporu. :P
JM
Może się mówi, ale i tak pan Kirchhoff się w grobie przewraca. Nie wiem kto to urobił
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 10 godzin
  • Postów:496
0

Wygląda ciekawie!
A jak rozdzielić pracę na poszczególne wątki?


AS
  • Rejestracja:około 8 lat
  • Ostatnio:9 miesięcy
  • Postów:48
0

Najpierw trzeba przygotować listę rzeczy do zrobienia. Ja używam zwykłego TStringList.

Przed uruchomieniem wątków roboczych robisz

Kopiuj
TaskList:=TStringList.Create; //TaskList jest zadeklorawana globalnie aby wszystkie wątki miały do niej dostęp podczas synchronizacji

TaskList.Add(FilePath) //ścieżka np. do jakiegoś pliku ,który trzeba przekonwertować w wątku

Dodajemy procedure CheckTaskList ,w której będziemy pobierać sobie coś do roboty. Lokalnie w wątku również deklarujemy sobie zmienną do której będziemy kopiować zadanie.

Kopiuj
type
  TWorkerThread = class(TThread)
  private
    { Private declarations }
    ThreadIndex:integer;  
    Task:string;
    procedure CheckTaskList;
  protected
    procedure Execute; override;
  end;

Dalej chyba już powinno być już zrozumiałe,

Kopiuj
procedure TWorkerThread.Execute;
begin

   repeat 

      Synchronize(CheckTaskList); 
      if Task<>'' then 
      begin
           {jakaś praca tutaj}
           Synchronize(UpdateProgress);
      end;

    until (Task='') or (Terminated=true);

end;
Kopiuj
procedure TWorkerThread.CheckTaskList;
begin

    if TaskList.Count>0 then
    begin
         Task:=TaskList.Strings[0];
         TaskList.Delete(0);
    end
    else Task:='';

end;
edytowany 11x, ostatnio: Atak_Snajpera
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 10 godzin
  • Postów:496
2

W końcu udało się zaimplementować prosty system obsługi wątków, zgodnie z sugestiami z tego wątku (oraz innego, który traktował o klasach WMI)...
Jeśli ktoś chce zobaczyć efekty, proszę bardzo (patrz załącznik). Wątki śmigają i można zobaczyć co w danej chwili jest robione...
Pierwsze uruchomienie trwa nieco dłużej, ponieważ pobierane są wszystkie klasy WMI, później są odczytywane z cache...

Program jest oczywiście dopiero w fazie początkowej (jest częścią większego projektu). Ma za zadanie wyświetlić najważniejsze informacje o sprzęcie oraz systemie. Jego istotą NIE jest wyświetlenie szczegółowych informacji, tylko podstawowych, które pozwolą zwykłemu użytkownikowi zorientować się na czym de facto pracują i dlaczego ten sprzęt taki słaby :P

Jeśli ktoś ma jakieś uwagi, chętnie wysłucham. Mogą być błędy (z pewnością będą :)). Do zrobienia mam Ustawienia aplikacji, Tworzenie Raportu (txt, html) oraz system obsługi wersji językowych.

Ps: Jeśli AV zgłosi pretensje, nie przejmować się. Plik jest czysty (od dawna próbuję znaleźć skuteczną metodę, żeby programy AV nie zgłaszały nieistniejących zagrożeń w pliku generowanym przez Delphi... ale to walka z wiatrakami. Wydaje się, że jedyną skuteczną metodą jest zgłaszanie false-positive bezpośrednio producentowi). Być może wykupienie podpisu cyfrowego (ale to jest za drogie i nie ma gwarancji).

-Pawel

SysInfo.zip


edytowany 1x, ostatnio: Pepe
GS
Sysinfo dobra robota ... :)
Pepe
Dzięki! Aktualnie pracuję nad raportem HTML... ma być ładny, przejrzysty i prosty... zobaczymy co wyjdzie :P
GS
@Pepe: zainstalowałem "ULTIMATE FILE MANAGER 7.9 FULL", dobra robota :) ale mam pytanie, bo pogubiłem się w opcjach, czy da się tak go skonfigurować aby wyszukiwanie plików w folderze działało na 'Alt+letter' ?
Pepe
Czy chodzi Ci o Quick Search? Wywołujesz go skrótem Ctrl+Alt + Litera (lub prawy Alt + Litera). Co do konfiguracji, to F1 -> Quick Search (a funkcjonalność tę można przypisać do dowolnego skrótu używając polecenia cm_ShowQuickSearch, jeśli dobrze rozumiem o co ci chodzi...)
GS
@Pepe: dziękuję. Tak, to miałem na myśli. Z prawym Altem działa, ale z Total Commandera mam nawyk że Quick Search działa jako Left Alt + litera.
AS
  • Rejestracja:około 8 lat
  • Ostatnio:9 miesięcy
  • Postów:48
1

Miodzio.Bardzo estetycznie wykonany program. Dobrze że używasz poprawnych jednostek binarnych (MiB,GiB...) zamiast MB,GB i traktowanie ich niepoprawnie jako MiB,GiB.
Taka pierdoła z mojej strony. Do wyświetlania np. użycia procesora nie używałbym standardowego ProgressBara bo to dziwnie wygląda. Użyłbym po prostu czegoś co nie generuje tej typowej animacji z "błyskiem".

Co do plucia się antywirków to znam to. Wystarczy że spakujesz .exeka np. głupim upx'em i Od razu jesteś traktowany jak "haksior"

edytowany 2x, ostatnio: Atak_Snajpera
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:Tuchów
  • Postów:12171
0
Atak_Snajpera napisał(a):

Miodzio.Bardzo estetycznie wykonany program. Dobrze że używasz poprawnych jednostek binarnych (MiB,GiB...) zamiast MB,GB i traktowanie ich niepoprawnie jako MiB,GiB.

W wielu miejscach jednostki używane są poprawnie, ale co najwyżej nieintuicyjnie. Najważniejsze jest to, aby używać prawidłowych obliczeń względem wybranej skali — dzielenia np. przez 1000 w przypadku MB oraz przez 1024 w przypadku MiB.

Taka pierdoła z mojej strony. Do wyświetlania np. użycia procesora nie używałbym standardowego ProgressBara bo to dziwnie wygląda. Użyłbym po prostu czegoś co nie generuje tej typowej animacji z "błyskiem".

Już kiedyś pokazywałem użytkownikowi @Pepe jak zrobić wykres zużycia, taki sam jak ma Win10. Łatwe to i ładne. Ale to był tylko test — we właściwej kontrolce takiego wykresu użyłbym antialiasingu. ;)

Wystarczy że spakujesz .exeka np. głupim upx'em i Od razu jesteś traktowany jak "haksior"

No to nie pakuj, bo to żadnego sensu nie ma, a tylko zwiększasz prawdopodobieństwo wystąpienia problemów u użytkownika końcowego.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 10 godzin
  • Postów:496
0

@Atak_Snajpera: Dzięki. UPX'a nie używam, właśnie z uwagi na fakt, że wtedy problemy są murowane... Rozmiar exe mi nie przeszkadza (i tak Delphi tworzy bardzo duże pliki wynikowe - ale w zamian dostaję wygodę i prostotę). A być może wydzielę obrazki (i inne zasoby) do osobnego pliku dll.

@furious programming: Użytkownik @Pepe pamięta bardzo dobrze i do dzisiaj jest wdzięczny za pomoc :) Jak już pisałem, jesteś dla mnie wzorem forumowicza - zawsze chętny od pomocy i zawsze przygotowany. Twoje posty są merytoryczne i pomocne.
Zaimplementuję kiedyś taką funkcjonalność (ale nie wiem czy w programie, bo w sumie ten akurat program jest dla mniej doświadczonych użytkowników... ale mam w planach stworzyć coś ala widżet na pulpit...


AS
  • Rejestracja:około 8 lat
  • Ostatnio:9 miesięcy
  • Postów:48
0

Dobre antivirki takie jak ten Microsoftowy automatycznie rozpakowują exeki przed analizą. Każdy inny ,który tego nie potrafi to przykład totalnej amatorki ze strony programisty i taki wyrób programopodobny nie jest warty instalowania. Ja używam upxa bo lubię jak binarki są małe. Taka stara szkoła...

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:Tuchów
  • Postów:12171
1
Atak_Snajpera napisał(a):

Dobre antivirki takie jak ten Microsoftowy automatycznie rozpakowują exeki przed analizą. Każdy inny ,który tego nie potrafi to przykład totalnej amatorki ze strony programisty i taki wyrób programopodobny nie jest warty instalowania.

Tyle że to nadal nie zmienia faktu, że sam sobie tym rzucasz kłody pod nogi, nie mając żadnego sensownego powodu. Im więcej użytkowników, którym wyskoczą powiadomienia o zagrożeniach (nieistotne czy poprawnie czy nie), tym gorzej dla Ciebie i Twojego oprogramowania. Ja wiem, że nie każdy chce wydawać kasę na podpis cyfrowy i zadbać o każdy szczegół, aby system nie traktował programu z podejrzliwością.

Ja używam upxa bo lubię jak binarki są małe. Taka stara szkoła...

To nie jest sensowny powód — taka „stara szkoła” miała sens 20 lat temu, a od wielu lat rozmiar plików wykonywalnych nie ma większego znaczenia, bo przeciętnemu użytkownikowi ani nie brakuje miejsca na dysku i pamięci RAM, ani też nie cierpi z powodu zbyt wolnego łącza internetowego. Poza tym łącze to i tak nieistotny element, bo program jeśli już to pobiera raz i z głowy.

Dziś pakowanie jakichkolwiek plików za pomocą UPX-a i podobnych narzędzi praktycznie w ogóle nie ma sensu. Być może są specyficzne przypadki, aby było to uzasadnione, ale we wszelkich typowych zastosowaniach uzasadnienia nie ma. Tym bardziej, że takie bezcelowe pakowanie powoduje dodatkowe problemy, które łatwo jest uniknąć po prostu nie używając tego typu narzędzi. No chyba, że lubisz się tłumaczyć użytkownikom z tego, dlaczego antywirusy blokują Twój program, to spoko. ;)


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 3x, ostatnio: flowCRANE
AS
  • Rejestracja:około 8 lat
  • Ostatnio:9 miesięcy
  • Postów:48
0

Antivirki i bez tego się często plują ,więc jeden pies. Nieodpowiednia faza księżyca i jesteś "keyloggerem/mallware/spyware/bitcoin minerem...". Dobrze że chociaż co raz więcej ludzi rezygnuje z tych głupich zewnętrznych często problematycznych anitirków i korzysta z wbudowanego w windows. Ten przynajmniej nigdy nie ma problemów z moimi programikami (pakowanymi czy nie).

edytowany 1x, ostatnio: Atak_Snajpera
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:Tuchów
  • Postów:12171
0

Heurystyka nie daleka od doskonałości i z tym niewiele można zrobić. Jednak jeśli ma się możliwość wykluczenia pewnej ilości fałszywych podejrzeń, to warto z niej skorzystać — tym bardziej, jeśli ta możliwość oznacza po prostu nie robienia niczego z plikiem wykonywalnym.

Natomiast niższy rozmiar pliku wykonywalnego można osiągnąć w sposób bezpieczny, po prostu usuwając z programu rzeczy niepotrzebne (np. nieużywane moduły z kodu źródłowego). Choć to i tak nie ma żadnego znaczenia, bo taka modułowa narośl nie waży więcej niż miegabajt. Tak więc wszelkie dodatkowe zabiegi mające na celu zmniejszenie rozmiaru pliku wykonywalnego po prostu nie mają żadnego sensu w dzisiejszych czasach.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 2x, ostatnio: flowCRANE
Pepe
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 10 godzin
  • Postów:496
0

Hey,
Jakiś czas temu pokazywałem jak program SysInfo działa (do gromadzenia informacji wykorzystuje WMI oraz wątki).

Od tego czasu udało mi się zaimplementować tworzenie raportu w formacie HTML (jeszcze chcę zrobić TXT). Dodałem również opcje (że można sobie poustawiać pod siebie). Aha, jeszcze dodam spis tresci (content/index) do raportu, żeby móc szybko przeskoczyć do interesującego nas działu).

W przyszłości jakieś wykresy i trochę info o programach (typu zainstalowane programy, działające procesy, etc).
Obciążenie procesora (ten pasek) zostanie zmieniony w przyszłości (prawdopodobnie na podział rdzenie/wątki).

Jak ktoś jest chętny, zapraszam do przetestowania. Jeśli macie jakieś sugestie, znajdziecie błąd - proszę o info.
Ps: Tłumaczenie nie jest zaimplementowane (program powinien być w języku angielskim, z wtrąceniami po polsku...

SysInfo.7z


edytowany 2x, ostatnio: Pepe
WL
  • Rejestracja:ponad 21 lat
  • Ostatnio:10 dni
  • Postów:1083
1
Pepe napisał(a):

Hey,
Jakiś czas temu pokazywałem jak program SysInfo działa (do gromadzenia informacji wykorzystuje WMI oraz wątki).

Od tego czasu udało mi się zaimplementować tworzenie raportu w formacie HTML (jeszcze chcę zrobić TXT).

Zamiast tworzyć HTML, TXT czy inne XLSX wypluj te wszystkie dane do JSON.
Potem mozesz użyć szablonów mustache żeby zrobić z tego HTML, TXT czy co tam chcesz.
No i łatwo można to sobie potem dostosować do własnych czy innych potrzeb.
Mam na myśli to, że dane to dane - a ich wizualizacja, to wizualizacja i powinno to być całkowicie rozdzielone.

Poza tym, możesz to zapiąć w usługę, która będzie te dane zwracała real-time np. do Grafany ;-)

Pepe
O w mordę! Nawet o takich narzędziach nie słyszałem :) Preferuję sam tworzyć warstwę wizualną, ponieważ jest dokładnie jak chcę.
WL
Wiesz w ogóle jak działa mustache? Bo ten argument z dostosowaniem do własnych potrzeb jest totalnie nietrafiony w tym kontekście. Właśnie chodzi o to, aby to łatwo można dostosować.
SK
Skoro piszemy już o mustache to tu jest implementacja dla Delphi/FPC: https://github.com/synopse/dmustache
Pepe
@wloochacz: Jak napisałem, dzisiaj się dowiedziałem, że coś takiego w ogóle istnieje. Mój projekt nie potrzebuje takich cudów. Ale, dobrze wiedzieć, że są możliwości użycia takich narzędzi.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.