Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.27;
Скачать: CL | DM;

Вниз

Создание мьютексов в основном потоке   Найти похожие ветки 

 
TUser ©   (2005-01-17 15:37) [0]

Почему этот код не работает? Есть 2 кнопки с кэпшенами "Create" и "Close". Если кликать на них в порядке "Create-Close-Create-Close-...", то ошибок не происходит. Если два раза подряд попытаться создать мьютекс, то, конечно, получается ERROR_ALREADY_EXISTS. Потом можем нажать Close, ошибку не пишет. Значит мьютекс мы уничтожили (насколько мне позволяют судить мои скромные познания). Потом опять нажмем на Create - и снова получем ERROR_ALREADY_EXISTS. Почему?
Кроме того, если два раза подряд нажать Close (при созданном мьютексе), то пишет "Extaernal error in C0000008", т.е. ошибка происходит внутри CloseHandle. Почему?

var m: cardinal;

{Button1.Caption = "Create"}
procedure TForm1.Button1Click(Sender: TObject);
var c: cardinal;
begin
 SetLastError(NO_ERROR);
 if GetLastError <> NO_ERROR then
   ShowMessage("---");
 m:=CreateMutex(nil,false,"TEST_MUTEX");
 c:=GetLastError;
 if c <> NO_ERROR then
   if c = ERROR_ALREADY_EXISTS then
     ShowMessage("Already exists")
     else
     ShowMessage("Unknown error");
end;

{Button2.Caption = "Close"}
procedure TForm1.Button2Click(Sender: TObject);
begin
 if not CloseHandle(m) then
   ShowMessage("Error");
end;


 
Digitman ©   (2005-01-17 15:49) [1]


> TUser ©   (17.01.05 15:37)  


давай-ка ты сначала не по-чукотски, а по-русски оформишь код :

var m: cardinal;

{Button1.Caption = "Create"}
procedure TForm1.Button1Click(Sender: TObject);
begin
m:=CreateMutex(nil,false,"TEST_MUTEX");
Win32Check(m <> 0);
end;

{Button2.Caption = "Close"}
procedure TForm1.Button2Click(Sender: TObject);
begin
Win32Check(CloseHandle(m));
end;

..

после этого приведи всевозможные секвенции "давки" на кнопки и видимые тобой рез-ты "давки" - тады уже будем обсуждать ..


 
TUser ©   (2005-01-17 16:09) [2]

С "чукотским" кодом
1. Create -> Close -> Create -> Close -> ... - никаких ошибок, все ОК
2. Close [Error, понятно - объекта еще нет]
3. Create -> Create [Already exists, т.к. объект уже есть] -> Close -> Create -> [Already Exists, непонятно - мы создаем объект, которого еще нет, т.к. предыдущий я уничтожил]
4. И вообще, при любом порядке нажимания, если я хоть один раз попытался создавать существующий мьютекс, то в этот момент (и все последующие) - получаю ERROR_ALREADY_EXISTS. После этого также любое нажатие Close дает Extaernal exception.

С "русским" кодом (порядок нажимания тот же)
1. Все ОК
2. [Handle does not exists]
3. Если сколько угодно раз нажать Create - то никаких ошибок нет. Это понятно, GreateMutex вернет хэндл существующего объекта, поэтому m <> 0, а Win32Check не вызовет никакого Raise. Непонятно, почему в таком случае чукотский код хуже русского.
4. Create -> любая последовательность нажатий -> Close -> Close [External exception, хотя должен показать просто "Error"]


Мне непонятны те результаты, которые я подчеркнул. Кто может объяснить?


 
Digitman ©   (2005-01-17 16:17) [3]

"русский" код - это код, полагающийся на автоинтерпретацию Win32-ошибок встроенным механизмом ф-ции Win32Check от БОРЛАНДА)

"чукотский" код полагается  на ОЖИДАЕМЫЕ ЧУКЧЕЙ ошибки, а не на любые возможные ошибки, могущие возникнуть, но не ожидаемые чукчей.


 
TUser ©   (2005-01-17 16:25) [4]

Но зато чукотский код должен (по моим понятниям) видеть, что мутекс уже создан. В русский этого не увидит. Или лучше пользоваться OpenMutex для таких целей вместо CreateMutex/GetLasError?
И что это за External exception?


 
TUser ©   (2005-01-17 16:29) [5]

Вот при такой постанове дела результаты точно такие же, как при [1]. Соотвественно - и вопросы те жу, что и в [2].

var m: cardinal;

procedure TForm1.Button1Click(Sender: TObject);
var c: cardinal;
begin
 m:=OpenMutex(MUTEX_ALL_ACCESS,false,"TEST_MUTEX");
 if m = 0 then begin
   m:=CreateMutex(nil,false,"TEST_MUTEX");
   Win32Check(m <> 0);
   end else
   ShowMessage("Already exists");
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 if not Win32Check(CloseHandle(m)) then
   ShowMessage("Error");
end;


 
Digitman ©   (2005-01-17 16:35) [6]


> TUser ©   (17.01.05 16:25) [4]
> Но зато чукотский код должен


он ничто никому не должен

он даст мне ПОЛНОЕ понимание происходящего, если ты укажешь в соответствии с
Button1Click (действие СОЗДАТЬ) и Button2Click (действие ЗАКРЫТЬ)
последовательность юзерских действий и то что юзер видит в рез-те конкр.посл-ти на экране.

"что вижу, то и пою" - великая штука !!


 
TUser ©   (2005-01-17 17:01) [7]


> Digitman ©   (17.01.05 16:35) [6]

Я в [2], вроде бы, описал. Create - нажатие на кнопку Create, Close - нажатие на кнопку Close ...


 
REA   (2005-01-17 17:07) [8]

>Потом можем нажать Close, ошибку не пишет. Значит мьютекс мы уничтожили

Или закрыли. (MSDN: The mutex object is destroyed when its last handle has been closed)


 
TUser ©   (2005-01-17 17:27) [9]


> REA   (17.01.05 17:07) [8]

Но тогда не получилось бы ERROR_ALREADY_EXISTS при последующем нажатии на Create, так?


 
Digitman ©   (2005-01-17 17:38) [10]


> TUser ©   (17.01.05 17:27) [9]


ты получил 2 ссылки на один и тот же объект.
объект будет уничтожен лишь после уничтожения обеих ссылок.



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

Текущий архив: 2005.02.27;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.023 c
14-1108038266
TUser
2005-02-10 15:24
2005.02.27
Полезный эксперт


14-1107738310
inew
2005-02-07 04:05
2005.02.27
Потерялся ComConst.dcu


3-1107157872
Mva
2005-01-31 10:51
2005.02.27
Вставка записи


6-1103490357
JaVa73
2004-12-20 00:05
2005.02.27
Оранизация web-форумов


1-1108201079
Kostik___
2005-02-12 12:37
2005.02.27
Генератор случ чисел