Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];

Вниз

Странный глюк при выходе из критической секции   Найти похожие ветки 

 
alexvan   (2003-06-16 10:13) [0]

У меня эта штука работает в XP и отказывается работать под WinME

unit twothreads;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TMainForm = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
procedure ThreadsDone(Sender: TObject);
end;

TFooThread = class(TThread)
protected
procedure Execute; override;
end;

var
MainForm: TMainForm;

implementation

{$R *.dfm}

const
MaxSize = 128;

var
NextNumber: Integer = 0;
DoneFlags: Integer = 0;
GlobalArray: array[1..MaxSize] of Integer;
CS: TRTLCriticalSection;

function GetNextNumber: Integer;
begin
Result:=NextNumber;
Inc(NextNumber);
end;

procedure TFooThread.Execute;
var
i: Integer;
begin
OnTerminate := MainForm.ThreadsDone;
EnterCriticalSection(CS);
for i := 1 to MaxSize do
begin
GlobalArray[i] := GetNextNumber;
Sleep(5);
end;
LeaveCriticalSection(CS);
end;

procedure TMainForm.ThreadsDone(Sender: TObject);
var
i: Integer;
begin
Inc(DoneFlags);
if DoneFlags = 2 then
for i:=1 to MaxSize do
ListBox1.Items.Add(IntToStr(GlobalArray[i]));
DeleteCriticalSection(CS);
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
InitializeCriticalSection(CS);
TFooThread.Create(False);
TFooThread.Create(False);
end;

end.


 
Digitman   (2003-06-16 10:42) [1]

В то время как в осн.потоке выполняется
ListBox1.Items.Add(IntToStr(GlobalArray[i])); (чтение эл-та массива)

в одном из доп.потоков в это время вполне может происходить
GlobalArray[i] := GetNextNumber; (запись того же эл-та массива)

Нонсенс ? Разумеется !

Резюме : неверно организована логика межпоточной синхронизации с использованием крит.секции (невовремя освобождаемой и удаляемой)





 
alexvan   (2003-06-16 10:47) [2]

Ошибка была вот в чём
if DoneFlags = 2 then
begin
for i:=1 to MaxSize do
ListBox1.Items.Add(IntToStr(GlobalArray[i]));
DeleteCriticalSection(CS);
end
</CODE


 
Digitman   (2003-06-16 11:03) [3]

все равно некорректно.

вот так в общем случае будет правильней :

procedure TMainForm.ThreadsDone(Sender: TObject);
var
i: Integer;
begin
EnterCriticalSection(CS); // другой поток вполне в этот момент может осуществлять доступ к ресурсу ! Необходим захват секции
try
for i:=1 to MaxSize do
ListBox1.Items.Add(IntToStr(GlobalArray[i]));
finally
LeaveCriticalSection(CS); // поработали с ресурсом - освободили секцию
Inc(DoneFlags);
if DoneFlags = 2 then /// потоков м.б. и 2 и 2000 и ...
DeleteCriticalSection(CS); // этот поток - последний осуществивший доступ к ресурсу, вот теперь можно и удалить секцию
end;
end;


 
alexvan   (2003-06-16 11:16) [4]

ОК. Спасибо



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.45 MB
Время: 0.031 c
1-84161
Aleksandr
2003-06-11 15:29
2003.06.26
Что надо сделать для


7-84791
Дельфятник
2003-04-18 11:05
2003.06.26
Какие события надо ловить чтобы программа реагировала на то, (+)


14-84750
agentru
2003-06-05 23:13
2003.06.26
Лучший сайт?


14-84630
Liso
2003-06-10 00:22
2003.06.26
zdrastwuj od padruga z polszy


3-83992
koks
2003-05-29 11:30
2003.06.26
эксклюзтвный доступ в dbf...... проблема





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский