Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.07.15;
Скачать: [xml.tar.bz2];

Вниз

WaitForSingleObject не ожидает закрытия мютекста   Найти похожие ветки 

 
DelphiN! ©   (2007-06-19 13:05) [0]

Пишу:


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
Почему так происходит??


 
clickmaker ©   (2007-06-19 13:11) [1]

а какой смысл создавать мьютекс с bInitialOwner = False и тут же приниматься ждать его? в том же процессе/потоке, причем


 
Игорь Шевченко ©   (2007-06-19 13:12) [2]


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


Ты получаешь, что Mutex для твоего процесса доступен. Это тебя удивляет ?


 
Сергей М. ©   (2007-06-19 13:15) [3]


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


Потому что мьютекс успешно занят тек.потоком при вызове тобой ф-ции WaitForSingleObject


 
Сергей М. ©   (2007-06-19 13:16) [4]


> Result := false //Error


Чтой-то вдруг error ?
В чем ты видишь ошибку при этом ?


 
DelphiN! ©   (2007-06-19 13:22) [5]


> clickmaker ©   (19.06.07 13:11) [1]


Я просто хочу проверить как ф-ия WaitForSingleObject ожидает закрытия мьютекста, тоесть я хочу получить от нее тайм аут в данном случае, просто для проверки, но тайм аут я не получаю!


> Игорь Шевченко ©   (19.06.07 13:12) [2]


Но ведь ф-ия WaitForSingleObject должна замораживать поток до тех пор, пока указатель MHandle существует, либо не был превышен тайм аут? Тоесть в моем случае я должен получить через некоторое время тайм аут, так как я не закрываю указатель MHandle, но вместо тайм аута я получаю в результате функии 0 и ее мгновенное завершение!


 
Anatoly Podgoretsky ©   (2007-06-19 13:28) [6]

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


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


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


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

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

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


 
Anatoly Podgoretsky ©   (2007-06-19 13:39) [8]

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

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


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


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


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

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


 
clickmaker ©   (2007-06-19 13:49) [10]


> [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);


 
Anatoly Podgoretsky ©   (2007-06-19 13:49) [11]

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

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


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


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

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

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


 
DelphiN! ©   (2007-06-19 14:02) [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 14:12) [14]

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:36) [15]


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


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


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


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

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


 
DelphiN! ©   (2007-06-19 19:05) [17]

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

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-20 08:58) [18]


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

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

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


 
DelphiN! ©   (2007-06-20 09:37) [19]


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


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


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

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

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


 
DelphiN! ©   (2007-06-20 10:13) [21]

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


 
DelphiN! ©   (2007-06-20 10:13) [22]

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


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

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


 
clickmaker ©   (2007-06-20 10:55) [24]


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

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


 
DelphiN! ©   (2007-06-20 11:54) [25]

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



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.07.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.053 c
2-1182156493
ssss
2007-06-18 12:48
2007.07.15
Как закруглить уголки формы ?


15-1181929921
Itonixxx
2007-06-15 21:52
2007.07.15
перекомпилировать Delphi код под Mac


6-1153741295
integerr
2006-07-24 15:41
2007.07.15
Internet Explorer + *.gif


2-1182073927
..::KraN::..
2007-06-17 13:52
2007.07.15
String to ANSI


2-1182156218
Kyro
2007-06-18 12:43
2007.07.15
Как узнать целосность mp3 файла





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский