![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно блокировать/разблокировать поток?
DevilDevil © (2007-11-07 08:22:00)Я не совсем о критических секциях говорю.
Известно, что поток должен простаивать относительно длительное время. Как правильнее реализовать Lock/UnLock для потомка TThread ?
Заранее спасибо
Loginov Dmitry (2007-11-08 23:18:00) [1]Функции Lock и UnLock в данном случае - простые и защищать критической секцией здесь нечего.
DevilDevil (2007-11-08 23:12:00) [2]недопонял... вот так правильно или нет :
procedure TMusicPlayerThread.Lock();
begin
try
FPlayer.BeginCriticalSection();
Event.ResetEvent();
finally
FPlayer.EndCriticalSection();
end;
end;
procedure TMusicPlayerThread.UnLock();
begin
try
FPlayer.BeginCriticalSection();
Event.SetEvent();
finally
FPlayer.EndCriticalSection();
end;
end;
Leonid Troyanovsky (2007-11-08 21:32:00) [3]
> Loginov Dmitry © (08.11.07 20:49) [41]
> Тело процедуры ты можещь защитить критической секцией (так
> наверно и нужно делать). Но в самих процедурах для блокировки
> / разблакировки потоков использовать мьютексы и критические
> секции нельзя, т.к. в этом случае пара Lock() / UnLock()
> всегда должна вызываться в одном и том же потоке. Так что
> здесь следует использовать Event.
А хватит Event'а, если тело большое?
--
Regards, LVT.
Loginov Dmitry (2007-11-08 20:49:00) [4]> и ещё вопрос: процедуры Lock() и UnLock() могут вызываться
> из обоих потоков; процедуры надо защищать критической секцией
> ?
Тело процедуры ты можещь защитить критической секцией (так наверно и нужно делать). Но в самих процедурах для блокировки / разблакировки потоков использовать мьютексы и критические секции нельзя, т.к. в этом случае пара Lock() / UnLock() всегда должна вызываться в одном и том же потоке. Так что здесь следует использовать Event.
DevilDevil (2007-11-08 15:01:00) [5]> Slym © (08.11.07 06:16) [38]
спасибо, что-то ступил, даже хелп не помотрел.
> Сергей М. © (08.11.07 10:25) [39]
тоже спасибо.
Сергей М. (2007-11-08 10:25:00) [6]
> DevilDevil (08.11.07 00:25) [31]
Есть готовыйкласс для работы с крит.секцией - TCliticalSection.
Все что нужно - создать его экз-р и ссылку на него раздать всем заинтересованным в синхронизации потокам.
Вход в секцию - метод Enter, выход - Leave.
И незачем изобретать новый кривой велосипед)
Slym (2007-11-08 06:16:00) [7]DevilDevil (08.11.07 0:25) [31]
ZeroMemory(@FCriticalSection, sizeof(TRTLCriticalSection));
а надо
InitializeCriticalSection(FCriticalSection)
Германн (2007-11-08 01:31:00) [8]
> DevilDevil (08.11.07 01:10) [36]
>
> > Германн © (08.11.07 01:00) [34]
>
> я что-то недогоняю, к чему ты клонишь. Взятие указателя
> конечно.
> А как ещё ты вызовешь ZeroMemory ?
>
1. Из справки:
VOID ZeroMemory(
PVOID Destination, // address of block to fill with zeros
DWORD Length // size, in bytes, of block to fill with zeros
);
Parameters
Destination
Points to the starting address of the block of memory to fill with zeros.
И ты решил, что @FCriticalSectionдаст тебе "адрес начала блока памяти"?
2. Из справки:
The @ operator returns the address of a variable, or of a function, procedure, or method; that is, @ constructs a pointer to its operand. For more information about pointers, see Pointers and pointer types. The following rules apply to @.
If X is a variable, @X returns the address of X.
Перевожу: @ оператор возвращает адрес самой переменной в памяти, а не адрес на который указывает её содержимое.
DevilDevil (2007-11-08 01:10:00) [9]> Германн © (08.11.07 01:00) [34]
я что-то недогоняю, к чему ты клонишь. Взятие указателя конечно.
А как ещё ты вызовешь ZeroMemory ?
KilkennyCat (2007-11-08 01:02:00) [10]
> что по-твоему означает конструкция @FCriticalSection?
собака ф будке, которую пора отремонтировать, либо собака ф бешенстве.
Германн (2007-11-08 01:00:00) [11]
> DevilDevil (08.11.07 00:46) [33]
>
> TRTLCriticalSection - структура, которую наверное как то
> надо инициализировать, которую возможно надо обнулять...
>
>
В Киеве бузина, а в огороде дядька.
Я тебя спрашивал про то, что по-твоему означает конструкция @FCriticalSection?
DevilDevil (2007-11-08 00:46:00) [12]TRTLCriticalSection - структура, которую наверное как то надо инициализировать, которую возможно надо обнулять...
Германн (2007-11-08 00:34:00) [13]А что ты хотел поиметь вот тут
> @FCriticalSection
DevilDevil (2007-11-08 00:25:00) [14]мда... такой вопрос...
AccessViolationв библиотеке ntdll.dll при выполнении кода:
procedure TMyClass.BeginCriticalSection();
begin
EnterCriticalSection(FCriticalSection);
end;
В конструктореTMyClassвызываетсяZeroMemory(@FCriticalSection, sizeof(TRTLCriticalSection));
umbra (2007-11-07 13:09:00) [15]
> а если я из основного потока вызову Thread.Free ?
>
если делать так, то не вижу смысла в строке
FreeOnTerminate := True;
Лучше вызовитеThread.Terminate:)
DevilDevil (2007-11-07 13:09:00) [16]вобщем, ладно.
я и так многое узнал, полученных знаний скорее всего хватит.
в случае чего ещё раз приду с возгласами "спасите-помогите !!!"
Участникам большое спасибо !
Сергей М. (2007-11-07 13:03:00) [17]
> DevilDevil © (07.11.07 12:58) [27]
> может через критическую секцию ?
>
Вот ее как раз и используй в теле DoSomething.
А на этом примере я показал один из вариантов управления потоком.
DevilDevil (2007-11-07 12:58:00) [18]> umbra © (07.11.07 12:04) [25]
разве ?
а если я из основного потока вызовуThread.Free?
> Сергей М. © (07.11.07 12:06) [26]
имхо кривовато. может через критическую секцию ?
Сергей М. (2007-11-07 12:06:00) [19]//обработчик сообщения TM_PLAY
FPlayState := psPlay;
while not PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) do
DoSomething(..);
//обработчик сообщения TM_PAUSE
FPlayState := psPause;
//обработчик сообщения TM_STOP
FPlayState := psStop;
//основной цикл поточной процедуры
while not Terminated and GetMessage(Msg, 0, 0, 0) do
Dispatch(Msg.message);
umbra (2007-11-07 12:04:00) [20]а зачем в деструкторе вообще писать
Terminated := true;, если он вызовется только после того, как свойствуTerminatedприсвоят значениеtrue?