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

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

WaitForSingleObject не ожидает закрытия мютекста


Страницы:   1 2

DelphiN! ©   (2007-06-19 13:05:00) 

Пишу:


var
 MHandle: THandle;

function Test: Boolean;
begin
 MHandle := CreateMutex(nil,false,'MyTest0000001');
 if WaitForSingleObject(MHandle,INFINITE) = 0 then
    Result := false//Error
 else
   Result := true;  //TimeOut
end;



И всегда мгновенно получаю в Result false
Почему так происходит??


DelphiN!   (2007-06-20 11:54:00) [1]

Спасибо, буду разбираться!


clickmaker   (2007-06-20 10:55:00) [2]


> [22] DelphiN! ©   (20.06.07 10:13)

никак. Они не по этим делам
если очень хочется таймаут, можно юзать TEvent или CreateEvent()


ага   (2007-06-20 10:54:00) [3]

А никак. Можно только использовать TryEnterCriticalSection


DelphiN!   (2007-06-20 10:13:00) [4]

А как объекту класса TCriticalSection назначить тайм аут?


DelphiN!   (2007-06-20 10:13:00) [5]

А как обекту класса TCriticalSection назначить тайм аут?


ага   (2007-06-20 09:53:00) [6]

а у вас каждый поток создаёт свой собственный мьютекс и захватывает его, поэтому никакой синхронизации нет вообще

Есть синхронизация. У него мьетекс именованный. А зывисает на Wait потому, что поток где-то блокируется, может диадлок. И критические секции сами собой это не устранят.


DelphiN!   (2007-06-20 09:37:00) [7]


> Однокамушкин   (20.06.07 08:58) [18]


Спасибо! С критическими секциями и проще и в моем случае без сбоев! :)


Однокамушкин   (2007-06-20 08:58:00) [8]


> DelphiN! ©   (19.06.07 19:05) [17]
> В проекте много потоковых функций, обезопасил всех их следующим
> образом :

Не обезопасили... чтобы потоки синхронизировались, они все должны использовать один и тот же мьютекс, а у вас каждый поток создаёт свой собственный мьютекс и захватывает его, поэтому никакой синхронизации нет вообще... смотрите Сергей М. ©   (19.06.07 14:12) [14]  - не зря Сергей сделал переменную h глобальной, а вот CreateMutex перед WaitForSingleObject поставил зря, мьютекс должен создаваться один раз и потом использоваться везде...

И в вашем случае вообще лучше пользоваться не мьютексами, а критическими секциями - они работвают быстрее... Преимущества мьютекса перед критической секцией заключаются в том, что мьютекс, во-первых, можно использовать для синхронизации потоков разных процессов, а критические секции - только одного, а во-вторых, мьютекс, в отличие от критической секции, может быть включен в список объектов синхронизации, ожидаемых совместно функцией WaitForMultipleObjects, а критическая секция всегда ожидается независимо... Но в вашем коде нет ни того, ни другого, так что пользуйтесь критической секцией...


DelphiN!   (2007-06-19 19:05:00) [9]

В проекте много потоковых функций, обезопасил всех их следующим образом :

function TDATA.GetHTTPParams(HTTPPost: String): String;
var
...
begin
 try
   //Lock thread
    GetHTTPParamsH := CreateMutex(nil,true,'GetHttpParams');
   WaitForSingleObject(GetHttpParamsH,INFINITE);


...

 finally
    ReleaseMutex(GetHTTPParamsH);
   CloseHandle(GetHTTPParamsH);

 end;
end;

Создаю потоки в событии OnGetThread компонента TServerSocket следующим образом :


procedure TMain.ServerSocketGetThread(Sender: TObject;
 ClientSocket: TServerClientWinSocket;
 var SocketThread: TServerClientThread);
begin
 SocketThread := TServerThread.Create(false, ClientSocket);
end;

procedure TServerThread.ClientExecute;
var
...
begin
 ...
 s := GetHTTPParams(HTTPPost);
...
end;

Но иногда поток зависает на WaitForSingleObject(GetHttpParamsH,INFINITE)

Это происходит если потоки создаются очень интенсивно, например если зажать обновление страницы на клиенте и серверу приходит очень много запросов.

С чем это может быть связано и как этого можно избежать?


Однокамушкин   (2007-06-19 15:26:00) [10]


> DelphiN! ©   (19.06.07 14:02) [13]
> Получается что вот эта процедура будет защищенной от одновременного
> доступа нескольких потоков?

Только в том случае, если они тоже пытаются захватить этот же мьютекс, прежде чем обращаться к совместно используемуму ресурсу...


DelphiN!   (2007-06-19 14:36:00) [11]


> Сергей М. ©   (19.06.07 14:12) [14]


Спасибо огромное!


Сергей М.   (2007-06-19 14:12:00) [12]

var
h: Handle;

function a(Data: Pointer): Integer; stdcall;
var
i,j: Integer;
begin
h := CreateMutex(nil,true,'MyMutex');
WaitForSingleObject(h,INFINITE);
//здесь преспокойно обращаешься к защищенному ресурсу
ReleaseMutex(h);
end;

var
i: Integer;
c: Cardinal;
begin
for i := 0 to 100 do
  CreateThread(nil,0,@a,nil,0,c);
end.


DelphiN!   (2007-06-19 14:02:00) [13]

Получается что вот эта процедура будет защищенной от одновременного доступа нескольких потоков?


var
 h: Handle;

procedure a;
var
 i,j: Integer;
begin
 WaitForSingleObject(h,INFINITE);
 h := CreateMutex(nil,true,'MyMutex');
 for i := 0 to 100 do
   for j := 0 to 100 do
     s := s+1;
 ReleaseMutex(h);
end;

var
 i: Integer;
 c: Cardinal;
begin
 for i := 0 to 100 do
   CreateThread(nil,0,@a,nil,0,c);
end.


Однокамушкин   (2007-06-19 13:56:00) [14]


> DelphiN! ©   (19.06.07 13:22) [5]
> Но ведь ф-ия WaitForSingleObject должна замораживать поток
> до тех пор, пока указатель MHandle существует, либо не был
> превышен тайм аут?

Нет, она затормаживает поток до тех пор, пока объект синхронизации находится в сигнализированном состоянии, а созданный вами мьютекс по умолчанию не в сигнализированном...

А вообще, вы, видимо, путаете с использованием WaitForSingleObject для ожидания окончания работы процесса или потока... но и там всё не так - сам поток или нить уже могут завершить работу, а объект будет продолжать существовать, если есть открытые хэндлы... просто такие объекты находятся в сигнализированном состоянии до тех пор, пока поток или процесс работают, а после их завершения переходят в несигнализированное, продолжая, тем не менее, существовать...


Anatoly Podgoretsky   (2007-06-19 13:49:00) [15]

> Сергей М.  (19.06.2007 13:47:09)  [9]

Это будет уже второй ответ, пока критичен первый


clickmaker   (2007-06-19 13:49:00) [16]


> [5] DelphiN! ©   (19.06.07 13:22)

ну вот пример использования

Процесс 1

hMutex := CreateMutex(nil, true, 'Mutex1'); // завладели мьютексом

// критический код

ReleaseMutex(hMutex); // отдали мьютекс
CloseHandle(hmutex);


Процесс 2

hMutex := OpenMutex(READ_CONTROL or SYNCHRONIZE, False, 'Mutex1');

// ждем, пока Процесс 1 завершит крит. код
WaitForSingleObject(hMutext, INFINITE); // или таймаут в мс

CloseHandle(hMutex);


Сергей М.   (2007-06-19 13:47:00) [17]


> Anatoly Podgoretsky ©   (19.06.07 13:39) [8]


Ну это само собой.

Можно и разрешить - все равно выхода по таймауту не будет.


Anatoly Podgoretsky   (2007-06-19 13:39:00) [18]

> Сергей М.  (19.06.2007 13:33:07)  [7]

Таймаута не будет по другой причине, поскольку он запрещен.


Сергей М.   (2007-06-19 13:33:00) [19]


> вместо тайм аута я получаю в результате функии 0 и ее мгновенное
> завершение


Да какой еще там таймаут ты ждешь ?

Не будет никакого таймаута, потому что мьютекс на момент вызова ф-ции ожидания гарантированно существует и им не владеет ни один из потоков.

Вызвав ф-цию ты тут же стал владельцем мьютекса, о чем тебя и известил нулевой рез-т вызова ф-ции.


Anatoly Podgoretsky   (2007-06-19 13:28:00) [20]

Таймаут? Шутишь?


Страницы:   1 2

Наверх

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