Форум: "WinAPI";
Текущий архив: 2005.09.25;
Скачать: [xml.tar.bz2];
ВнизПроблема с потоками Найти похожие ветки
← →
ingine (2005-07-28 14:11) [0]Есть несколько потоков,обрабатывающих некую информацию, при завершении каждого из потоков должна вызываться процедура находящаяся в основном потоке программы, причем другие потоки в этот момент не должны иметь доступа к этой процедуре - как реализовать???
← →
Reindeer Moss Eater © (2005-07-28 14:15) [1]TCriticalSection
или
InitializeCriticalSection
← →
ingine (2005-07-28 14:20) [2]
section:=TCriticalSection.create;
section.enter;
myprocedure(param1:string;param2:integer);
section.leave;
section.free;
проблема в том (я не знаю как это объяснить) что поток не ожидает завершения myprocedure, а сразу выходит из критической секции...
← →
Alexander Panov © (2005-07-28 14:24) [3]Неверное использоание критических секций.
1. Критическая секция должна быть создана заранее.
2. КС должна быть доступна обоим потокам.
Пример:var
IniCS: RTL_CRITICAL_SECTION;
implementation
procedure EnterIniCS;
begin
EnterCriticalSection(IniCS);
end;
procedure LeaveIniCS;
begin
LeaveCriticalSection(IniCS);
end;
function GetParm(const aSec,aParm: String): String;
var
ini: TIniFIle;
begin
Result := "";
ini := TIniFile.Create(GetIniName);
try
EnterIniCS;
Result := ini.ReadString(aSec,aParm,"");
LeaveIniCS;
finally
ini.Free;
end;
end;
← →
Reindeer Moss Eater © (2005-07-28 14:28) [4]Входить в КС (единственную) надо в той общей процедуре главного потока.
← →
ingine (2005-07-28 14:31) [5]это всего лишь пример,
критическая секция у меня создается при обработке TMyThread.create
inherited create(true);
Section:=TCriticalSection.Create;
self.FreeOnTerminate:=true;
self.resume;
и высвобождается при TMyThread.free
Section.free;
,
а используется в TMyThread.execute
section.enter;
myprocedure(param1:string;param2:integer);
section.leave;
← →
ingine (2005-07-28 14:38) [6]как добится ожидания завершения myprocedure ???
← →
Alexander Panov © (2005-07-28 14:39) [7]Обрати внимание - 1. Критическая секция должна быть создана заранее.
ОДНА критическая секция.
В нее-то и должен каждый поток пытаться войти.
← →
ingine (2005-07-28 14:46) [8]
> Обрати внимание - 1. Критическая секция должна быть создана
> заранее.
Заранее это как??? Вне потока????
← →
Alexander Panov © (2005-07-28 14:50) [9]ingine (28.07.05 14:46) [8]
Заранее это как??? Вне потока????
Просто прими как данность, что некоторый код защищается
одной и лишь одной критической секцией.
Т.е. каждый попток, который пыьается выполнить некий код, должен войти именно в одну и ту же для всех потоков критическую секцию.
Таким образом, это и будет ответом на вопрос из [8].
← →
Alexander Panov © (2005-07-28 14:51) [10]ingine (28.07.05 14:46) [8]
Заранее это как??? Вне потока????
Ты можешь создать КС в потоке. Но только один(!) раз и для всех потоков для защиты участка кода. Для защиты другого участка кода ты должен использовать другую критическую секцию, но тоже одну.
← →
Reindeer Moss Eater © (2005-07-28 14:55) [11]>как добится ожидания завершения myprocedure ???
Этого не надо добиваться.
Это произойдет само по себе.
← →
Digitman © (2005-07-28 15:37) [12]
> ingine
представь себе, что на оживленной улице каждый водитель или пешеход имеет своего собственного регулировщика дорожного движения .. и ни один регулировщих о других таких же как он ничего не знает - каждый машет палкой как ему вздумается ..
← →
ingine (2005-07-28 16:13) [13]
> Alexander Panov © (28.07.05 14:24) [3]
> Неверное использоание критических секций.
> 1. Критическая секция должна быть создана заранее.
> 2. КС должна быть доступна обоим потокам.
>
> Пример:
>
> var
> IniCS: RTL_CRITICAL_SECTION;
>
> implementation
>
> procedure EnterIniCS;
> begin
> EnterCriticalSection(IniCS);
> end;
>
> procedure LeaveIniCS;
> begin
> LeaveCriticalSection(IniCS);
> end;
>
> function GetParm(const aSec,aParm: String): String;
> var
> ini: TIniFIle;
> begin
> Result := "";
> ini := TIniFile.Create(GetIniName);
> try
> EnterIniCS;
> Result := ini.ReadString(aSec,aParm,"");
> LeaveIniCS;
> finally
> ini.Free;
> end;
> end;
при таком использование КС - вылезает access violation в ntdll.dll при enterinics;
← →
Alexander Panov © (2005-07-28 16:18) [14]Ну а создавать CS кто будет?
Сначала нужно выполнить инициализацию.
У меня этот пример из отдельного модуля. Там сделано так:
initialization
InitializeCriticalSection(iniCS);
finalization
DeleteCriticalSection(iniCS);
end.
← →
Digitman © (2005-07-28 16:47) [15]
> ingine (28.07.05 16:13) [13]
в ассоциацию с регулировщиком вник ?
движение на перекрестке должен регулировать ОДИН регулировщик...
его уполномачивает не тот самый водила и не тот самый пешеход, что пересекает тот самый перекресток по своим делам в заданный момент времени, а тот кто ответственен за безопасность дорож.движения на данном перекрестке
т.о., чтобы бардака на перекрестке не было, сначала требуется поставить туда регулировщика, а уж потом разрешить проезд через перекресток
теперь - ассоциации :
перекресток - ресурс (неразделяемый, т.е. позволяющий одновременно движение лишь в неких обусловленных направлениях)
регулировщик - защита ресурса
водилы/пешеходы - пользователи ресурса
← →
ingine (2005-07-28 17:20) [16]вник - все работает всем спасибо :-)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.09.25;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.043 c