![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создание мьютексов в основном потоке
TUser © (2005-01-17 15:37:00)Почему этот код не работает? Есть 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 17:38:00) [1]
> TUser © (17.01.05 17:27) [9]
ты получил 2 ссылки на один и тот же объект.
объект будет уничтожен лишь после уничтожения обеих ссылок.
TUser (2005-01-17 17:27:00) [2]
> REA (17.01.05 17:07) [8]
Но тогда не получилось бы ERROR_ALREADY_EXISTS при последующем нажатии на Create, так?
REA (2005-01-17 17:07:00) [3]>Потом можем нажать Close, ошибку не пишет. Значит мьютекс мы уничтожили
Или закрыли. (MSDN: The mutex object is destroyed when its last handle has been closed)
TUser (2005-01-17 17:01:00) [4]
> Digitman © (17.01.05 16:35) [6]
Я в [2], вроде бы, описал. Create - нажатие на кнопку Create, Close - нажатие на кнопку Close ...
Digitman (2005-01-17 16:35:00) [5]
> TUser © (17.01.05 16:25) [4]
> Но зато чукотский код должен
он ничто никому не должен
он даст мне ПОЛНОЕ понимание происходящего, если ты укажешь в соответствии с
Button1Click (действие СОЗДАТЬ) и Button2Click (действие ЗАКРЫТЬ)
последовательность юзерских действий и то что юзер видит в рез-те конкр.посл-ти на экране.
"что вижу, то и пою" - великая штука !!
TUser (2005-01-17 16:29:00) [6]Вот при такой постанове дела результаты точно такие же, как при [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;
TUser (2005-01-17 16:25:00) [7]Но зато чукотский код должен (по моим понятниям) видеть, что мутекс уже создан. В русский этого не увидит. Или лучше пользоваться OpenMutex для таких целей вместо CreateMutex/GetLasError?
И что это за External exception?
Digitman (2005-01-17 16:17:00) [8]"русский" код - это код, полагающийся на автоинтерпретацию Win32-ошибок встроенным механизмом ф-ции Win32Check от БОРЛАНДА)
"чукотский" код полагается на ОЖИДАЕМЫЕ ЧУКЧЕЙ ошибки, а не на любые возможные ошибки, могущие возникнуть, но не ожидаемые чукчей.
TUser (2005-01-17 16:09:00) [9]С 'чукотским' кодом
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 15:49:00) [10]
> 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;
..
после этого приведи всевозможные секвенции "давки" на кнопки и видимые тобой рез-ты "давки" - тады уже будем обсуждать ..