Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно блокировать/разблокировать поток?


Страницы:   1 2 3

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?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо