Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.09.25;
Скачать: CL | DM;

Вниз

Проблема с потоками   Найти похожие ветки 

 
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 вся ветка

Текущий архив: 2005.09.25;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.032 c
3-1123734628
Fedor
2005-08-11 08:30
2005.09.25
Запрос для связанных таблиц


1-1125387238
Darmidon
2005-08-30 11:33
2005.09.25
Свернуть все окна + Shell32.dll


4-1122777656
GETWORD
2005-07-31 06:40
2005.09.25
Определение момента поного открытия MS Word


6-1117279379
KorvinOE
2005-05-28 15:22
2005.09.25
Выставить TimeOut для входящих у IdTCPServer


1-1125716526
Ivanov
2005-09-03 07:02
2005.09.25
*.pak - архив