Autor Téma: Vlákna a kritické sekce  (Přečteno 665 krát)

Offline age.new

  • Hrdina
  • ****
  • Příspěvků: 316
  • Karma: 0
Vlákna a kritické sekce
« kdy: 28-02-2020, 16:35:23 »
Zdravím,

mohl by mi někdo poradit zda je následující řešení v pořádku?

Mám aplikaci, která si vytváří vlákna (TThread) pro ukládání, načítání atd. Když si vytvořím proceduru:

Kód: Delphi [Vybrat]
  1. procedure READWRITE(const mode: integer; var in_buff: TBuffer);
  2. begin
  3. [b]ENTERCRITICALSECTION;[/b]
  4.  
  5. case mode of
  6.   1: global_buff := in_buff;
  7.   2: in_buff       := global_buff;
  8. end;
  9.  
  10. [b]LEAVECRITICALSECTION;[/b]
  11. end;
  12.  

Kód je spíše jen pro náčrt otázky. Jde o to, že tato procedura pracuje s global_buff proměnnou do které mohu pomocí této procedury zapisovat, nebo číst. Přístup k ní má aplikace i vlákna. Zajistí mi označení kritické sekce to, že nedojde k obsluze kódu naráz například z aplikace a jiného vlákna? To znamená, že nemůže dojít k zápisu a čtení naráz ze dvou různých vláken?

Z toho plyne ještě další otázka: Když jedno vlákno obsluhuje kritickou sekci, tak zbylá vlákna čekají před sekcí? I samotná aplikace? Takže když jedno vlákno bude kritickou sekci obsluhovat dlouhou dobu, může aplikace vytuhnout?

Ještě bych měl malou otázku k vytížení vláken. Když budu mít v Execute nekonečný cyklus přerušitelný pouze zrušením vlákna nebo aplikace, tak pomůže vložení sleep() procedury k tomu, aby se snížilo aktuální vytížení výkonu samotného jádra? A nebo je lepší způsob, jak "zpomalit" nekonečný cyklus v Execute proceduře vlákna?

Děkuji.

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1559
  • Karma: 37
    • Pepak.net
Re:Vlákna a kritické sekce
« Odpověď #1 kdy: 28-02-2020, 16:44:00 »
Zajistí mi označení kritické sekce to, že nedojde k obsluze kódu naráz například z aplikace a jiného vlákna?
Ano.

Citace
Když jedno vlákno obsluhuje kritickou sekci, tak zbylá vlákna čekají před sekcí? I samotná aplikace? Takže když jedno vlákno bude kritickou sekci obsluhovat dlouhou dobu, může aplikace vytuhnout?
Ano.

Citace
Ještě bych měl malou otázku k vytížení vláken. Když budu mít v Execute nekonečný cyklus přerušitelný pouze zrušením vlákna nebo aplikace, tak pomůže vložení sleep() procedury k tomu, aby se snížilo aktuální vytížení výkonu samotného jádra?
Ano.

Citace
A nebo je lepší způsob, jak "zpomalit" nekonečný cyklus v Execute proceduře vlákna?
Ano. CreateEvent, WaitForSingleObject, SetEvent (z jiného vlákna, pokud se má pauza přerušit ihned).

Offline age.new

  • Hrdina
  • ****
  • Příspěvků: 316
  • Karma: 0
Re:Vlákna a kritické sekce
« Odpověď #2 kdy: 28-02-2020, 17:16:45 »
Děkuji za odpovědi.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3343
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Vlákna a kritické sekce
« Odpověď #3 kdy: 28-02-2020, 20:44:55 »

Citace
A nebo je lepší způsob, jak "zpomalit" nekonečný cyklus v Execute proceduře vlákna?
Ano. CreateEvent, WaitForSingleObject, SetEvent (z jiného vlákna, pokud se má pauza přerušit ihned).
V zasade pouzivam takovouhle obecnou konstrukci:
Kód: Delphi [Vybrat]
  1.         repeat
  2.           WxRes := WaitForMultipleObjects(ord(high(FEvents))-ord(low(FEvents))+1, addr(FEvents), FALSE, maxPOP3ThreadScan);
  3.           WxErr := GetLastError;
  4.           case WxRes of
  5.             WAIT_FAILED:
  6.               begin
  7.                 TraceFmt('!! WAIT_FAILED occured. LastError=%s',[FormatSysError(WxErr)]);
  8.                 Break;
  9.               end;
  10.             WAIT_TIMEOUT:
  11.               begin
  12.                 _ExecuteAction;
  13.               end;
  14.             WAIT_OBJECT_0+ord(eoteKill):
  15.               begin
  16.                 Terminate;
  17.                 Break;
  18.               end;
  19.             WAIT_ABANDONED_0..WAIT_ABANDONED_0+ord(high(FEvents)):
  20.               raise xInternal.CreateFmt(sx_ThreadAbandoned,[WxRes-WAIT_ABANDONED_0]);
  21.             else
  22.               ;
  23.           end;
  24.         until FALSE;
  25.