![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Странный deadlock [D7, WinXP]
mt2 © (2008-01-14 15:37:00)Hi,
unit Unit1;
// Delphi-7
// Странный deadlock, см. строки:
// Почему эта программа зависает без sleep(0) ?
// Если n=200, то эта программа работает без sleep(0). Почему?
// Испытано под MS Windows XP SP2, CPU Intel Pentium-4 3.0 GHz
// и на другом CPU Intel Pentium-4 3.2 GHz
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TTestThread = class(TThread)
constructor Create (CreateSuspended : Boolean; eventHnd : THandle; i : integer);
private
{ Private declarations }
ind : integer;
syncEvent : THandle;
protected
procedure Execute; override;
end;
var
Form1: TForm1;
events : array [0..7] of THandle;
thr : array [0..7] of TTestThread;
stop : Boolean;
n : integer;
calc : array [1..8] of integer;
implementation
{$R *.dfm}
constructor TTestThread.Create (CreateSuspended : Boolean; eventHnd : THandle; i : integer);
begin
inherited Create (CreateSuspended);
syncEvent := eventHnd;
ind := i;
end;
procedure TTestThread.Execute;
begin
{ Place thread code here }
repeat
inc(calc [ind],n);
SetEvent (syncEvent);
suspend;
until stop;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
for i:=1 to 8 do
calc [i] := i;
stop := false;
for i:=0 to 7 do
events [i] := CreateEvent (nil, true, false, PChar('testEvent'+intToStr(i)));
for i:=0 to 7 do
thr[i] := TTestThread.Create(true, events [i],i+1);
n := 0;
repeat
inc (n);
thr[0].Resume;
thr[1].Resume;
thr[2].Resume;
thr[3].Resume;
thr[4].Resume;
thr[5].Resume;
thr[6].Resume;
thr[7].Resume;
waitForMultipleObjects (8, @events, true, INFINITE);
ResetEvent (events [0]);
ResetEvent (events [1]);
ResetEvent (events [2]);
ResetEvent (events [3]);
ResetEvent (events [4]);
ResetEvent (events [5]);
ResetEvent (events [6]);
ResetEvent (events [7]);
sleep(0); // Почему эта программа зависает без sleep(0) ?
until n=1000; // Если n=200, то эта программа работает без sleep(0). Почему?
Memo1.Lines.Add('n= '+ intToStr(n));
for i:=1 to 8 do
Memo1.Lines.Add(intToStr(calc[i]));
end;
end.
ага (2008-01-14 19:49:00) [21]На многопроцессорной тачке это могло долго не проявиться. А могло и сразу. В общем, все единл фтопку.
ага (2008-01-14 19:46:00) [22]
> Такой момент, когда все потоки одного успели вызвать
Такой момент, когда все потоки кромеодного успели вызвать
ага (2008-01-14 19:45:00) [23]А, ну да, еще ж про Sleep. Sleep усыпляет на квант планировщика главный поток, в результате наш несчастный "последний" поток получает возможность вызвать свой Suspend раньше, чем главный поток вызовет ему Resume.
> Сергей М. © (14.01.08 17:11) [6]
Ну че абракадабра-то? Нормально сделал, выдернул проблему, лишнего не постил.
ага (2008-01-14 19:40:00) [24]
> Если n=200, то эта программа работает без sleep(0)
Эт тока кажется. А виснет вот почему.
Такой момент, когда все потоки одного успели вызвать SetEvent и уйти в Suspend. В какой-то момент последний поток успевает вызвать SetEvent и в этот момент планировщик у него отбирает процессор и отдает гланому - главный-то поток интерфейсный, у его окна фокус, потому у него приоритет повыше.
Главный поток сбрасывает все эвенты и резюмит все потоки. Все кроме последнего - он-то еще не успел уснуть и Resume ему по барабану. Далее главный поток уходит в WaitFor... и процессор достаетс последнему из потоков. Тот просыпается и вызывает свой Suspend.
Все, аллес. Спит главный поток, потому что у нег WaitAll = true, спит наш несчастный последний поток в своем Suspend. Отработают свои циклы и уснут все остальные потоки. Все спят, и разбудить их некому. Кроме TerminateProcess.
Б-р-р-р...
Сергей М. (2008-01-14 17:11:00) [25]
> отловил bug и минимизировал
И ?
> Лишние детали будут не по теме
Продолжай париться.
> Попробуй для начала запустить
Да нахрен оно мне надо
> что получается, и почему.
Получится хня.
Почему ?
потому что абракадабра в коде.
icWasya (2008-01-14 17:09:00) [26]после waitForMultipleObjects (8, @events, true, INFINITE);
ResetEvent не нужно
mt2 (2008-01-14 16:36:00) [27]ТЗ будет слишком долго, прога сложная, отловил bug и минимизировал. Лишние детали будут не по теме. Попробуй для начала запустить у себя и сообщи, что получается, и почему.
Сергей М. (2008-01-14 16:13:00) [28]Что это вообще за хня ?
Изложи ТЗ.
mt2 (2008-01-14 15:48:00) [29]:) может они (странности) не только мои? но и ОС? - тогда и тебя поздравляю ;))))))))))
Сергей М. (2008-01-14 15:44:00) [30]Поздравляем тебя с имеющими тебя странностями.