Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Mutex - один поток захватывает, а другой освобожда


Автор: Gershkovich 20.2.2006, 18:00
Такая ситуация:

Первый поток захватывает мутех:
WaitForSingleObject(my mutex);


Может ли другой поток освободить его ???
CloseHandle(my mutex)

Или это должен сдделать тот поток, который его захватил ??

Спасибо.

Автор: _hunter 20.2.2006, 18:06
должен освобождать захвативший поток

Автор: Gershkovich 21.2.2006, 10:49
А как тогда выкрутится ?

Я использую мутехи для lock\unlock объекта.

Т.е. поток N1 лочит объект (простой объект типа TObject ) и передает
его потоку N2.

Поток N2 поработав с объектом его раздочивает.

это выглядит примерно так:


Код

function TMyObject.Lock(TimeOut : cardinal) : boolean;
var WaitResult : TWaitResult;
begin
  Result:= false;

  WaitResult:= WaitForSingleObject(_mutex, TimeOut);
  if (WaitResult=wrSignaled) and not self.Locked then begin
    self.Locked:= true;
    Result:= true;
    _mutex.SetEvent;
  end;
end;

procedure TMyObject.UnLock;
begin
  WaitForSingleObject(_mutex, INFINITE);
  Locked:= false;
  _mutex.SetEvent;
end;


в процедуре UnLock настоящие чудеса: процедура вызывается
но Locked остается true без эксепшнов.
Иногда просто зависает.

Такое впечатление что я что-то упустил.
Подкиньте идею куда копать.

Спасибо.


Автор: _hunter 21.2.2006, 11:35
а зачем поток N2 объект раздочивает ( интересно, что этот термин значит )?
этим, по правилам, первый поток должен заниматься. в этом случае второй поток забирает мьютекс, а первый, по его (мьютекса) освобождению раздочивает объект.

Автор: Gershkovich 21.2.2006, 12:16
Извините за опечатку.

раздочивает - правильно писать разЛочивает
т.е. вызывает метод Unlock у объекта.

Насчет правил я не спорю.
Но мне надо именно такая модель - пока два потока работают с объектом
третий не мог бы вмешаться.
Я хотел реализовать модель захвата объекта - это значит корректно
выставить флаг Locked , чтобы третий поток не мог обратиться к нему.

Т.е. поток N3 пытается вызвать Lock примерно так :
Код

if obj.Lock(1000) then begin
  // process object
end else begin
  // exit procedure
end;


Мне кажется такое возможно, но мне не хватает знаний для реализации

Автор: _hunter 21.2.2006, 13:13
если ты так хочеш уйти от синхронизации мьютексами -- используй критические секции ( в нее по-очереди сможет входить любой поток ). и в этой секции и выставляй Locked/UnLocked.
но ты просто будеш дублировать работу мьютекса

Автор: Akina 21.2.2006, 13:59
Цитата(Gershkovich @ 21.2.2006, 11:49 Найти цитируемый пост)
Т.е. поток N1 лочит объект (простой объект типа TObject ) и передает
его потоку N2.
Поток N2 поработав с объектом его разлочивает.

Я не понимаю - что мешает потоку 2 после работы вернуть объект потоку 1 для разлочивания?

Автор: Gershkovich 21.2.2006, 18:18
Цитата(Akina @ 21.2.2006, 13:59 Найти цитируемый пост)
Я не понимаю - что мешает потоку 2 после работы вернуть объект потоку 1 для разлочивания?


Мешает хотя бы то что поток 1 давно уже завершился.

Автор: Snowy 21.2.2006, 18:23
Если он завершился, то уже никак не может ничего держать.

Автор: Gershkovich 22.2.2006, 10:28
Если кому интересно- я решил задачу использова Event

Код

function TMyObject.Lock(TimeOut : cardinal) : boolean;
begin
  Result:= WaitForSingleObject(event, TimeOut) = WAIT_OBJECT_0;
end;

procedure TMyObject.UnLock;
begin
  SetEvent(event);
end;



Поток 1 вызывает Lock, тем самым сбрасывая event
поток 2, завершив свои дела с объектом, восстанавливает event

Поток 3 пытается
Код

if MyObject.Lock(1000) then begin
  //process  MyObject
end esle begin
  //Skip processing
  Exit;
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)