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

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

Вопрос про многопоточность.


Страницы:   1 2 3

@!!ex ©   (2007-12-24 18:46:00) 

Чем грозит такая ситуация:
есть boolean массив.
есть дополнительный поток, который постоянно перебирается все элементы массива и меняет их значения.
Из основного потока периодически берутся значения массива.
Никакой синхронизации нет...


oxffff   (2007-12-24 20:47:00) [1]


> DiamondShark ©   (24.12.07 20:41) [48]
>
> > oxffff ©   (24.12.07 20:36) [46]
>
> Ты тормоз. ;)


Плакалъ.А ты замерь пересылку.
А прикинь нажал кнопку, и никакого результата.


@!!ex   (2007-12-24 20:46:00) [2]

Товарищи модераторы, пожалуйста закройте ветку!
Не хочеться, чтобы два хороших человека ругались из-за ерунды!
Задача решена через GetAsyncKeyState:

procedure TKeys.Update;
var
 Index:integer;
 Key:Smallint;
begin
 for Index:=0 to 255 do begin
   Key:=GetAsyncKeyState(Index);
   if Key And $8000<> OldKeys[Index] And $8000 then  begin
     Keys[Index]:=(Key And $8000)<>0;
     OldKeys[Index]:=Key;
   end;
 end;
end;


Sapersky, спасибо!


DiamondShark   (2007-12-24 20:41:00) [3]


> oxffff ©   (24.12.07 20:36) [46]

Ты тормоз. ;)


oxffff   (2007-12-24 20:38:00) [4]


> @!!ex ©   (24.12.07 20:33) [45]


Другой поток может вообще не увидить никакого обновления в течении длительного времени на мнопроцессорной машине.
Жмешь кнопку и никакого отклика.
Поток чтения не видит обновления.


oxffff   (2007-12-24 20:36:00) [5]


> DiamondShark ©   (24.12.07 20:31) [43]


Ты реально даже прочитать не можешь SDK.

An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue.


@!!ex   (2007-12-24 20:33:00) [6]

> Ты реально бестолковый дятел.
> Увы запись байта атомарна.
> А вот состояние всего массива не согласовано.

ну и что?
Отклик за 20 мс(это примерно 40 фпс) никто не заметит. Ибо ниочем.
Так что то, что обновится только полокина массива - это фигня.
Меня волновало именно то, что не будет AV.


oxffff   (2007-12-24 20:33:00) [7]


> DiamondShark ©   (24.12.07 20:28) [41]


А ты читай книжки и набивай всою пустую башку.
Родился в день знаний и не хрена не знаешь.
Еще и статьи пишешь.
Как тебя только допустили до статей?


DiamondShark   (2007-12-24 20:31:00) [8]


> oxffff ©   (24.12.07 20:26) [40]
>
> А если прикинь нажал кнопку, а результата нет.

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

Трагедия, однако. ;)

Опять фантазии. Теперь на тему критичности приложения.


oxffff   (2007-12-24 20:31:00) [9]


> @!!ex ©   (24.12.07 20:24) [39]


C DI время отклика будет лучше. Гораздо.
Работать очень просто.

Код с моего движка.

DirectInput8.CreateDevice(GUID_SysMouse,DirectInputDeviceMouse,nil);
//if DirectInputDevice.SetCooperativeLevel(Handle,DISCL_BACKGROUND or DISCL_NONEXCLUSIVE)=DI_OK then ;//showmessage('DI_OK');

//DirectInputDeviceMouse.SetCooperativeLevel(Handle,DISCL_FOREGROUND);
DirectInputDeviceMouse.SetCooperativeLevel(Handle,DISCL_NONEXCLUSIVE or DISCL_BACKGROUND);
DirectInputDeviceMouse.SetDataFormat(c_dfDIMouse);
DirectInputDeviceMouse.Acquire;

DirectInput8.CreateDevice(GUID_SysKeyboard,DirectInputDeviceKeyboard,nil);
DirectInputDeviceKeyboard.SetCooperativeLevel(Handle,DISCL_FOREGROUND);
DirectInputDeviceKeyboard.SetDataFormat(c_dfDIKeyboard);
DirectInputDeviceKeyboard.Acquire;

Обработка

param.DirectInputDeviceKeyboard.GetDeviceState(sizeof(diKeys),@diKeys);
 if diKeys[DIK_ESCAPE]=$80 then param.DirectInputDeviceMouse.Unacquire;
 if diKeys[DIK_W]=$80 then Camera.Walk(300);
 if diKeys[DIK_S]=$80 then Camera.Walk(-300);
 if diKeys[DIK_A]=$80 then Camera.Yaw(-0.005);
 if diKeys[DIK_D]=$80 then Camera.Yaw(0.005);
if  param.DirectInputDeviceMouse.GetDeviceState(sizeof(DIMOUSESTATE),@MouseState)=DI _OK then
         begin
         if MouseState.rgbButtons[0]>0 then Camera.Walk(300);
         if MouseState.rgbButtons[1]>0 then Camera.Walk(-300);
         if MouseState.lX<>0 then  Camera.Yaw(-MouseState.lX/900);
         if MouseState.lY<>0 then  Camera.Pitch(-MouseState.lY/900);
         Camera.CalculateMatrixView(matrixView);
         setTransform(D3DTS_VIEW,matrixView);
         end;


DiamondShark   (2007-12-24 20:28:00) [10]


> Нет, Я это твоя проблема.

Всё. Пипец. Ржу до слёз. :)

Лечись от манечки.


oxffff   (2007-12-24 20:26:00) [11]


> Sapersky   (24.12.07 20:20) [37]


А если прикинь нажал кнопку, а результата нет.
Так что увы это критично.


@!!ex   (2007-12-24 20:24:00) [12]

> Также странно и желание автора вопроса использовать GetKeyboardState
> в отдельном потоке. Неужели в основном не работает?
> Как вариант, есть ещё GetAsyncKeyState/DirectInput.

http://www.delphimaster.ru/cgi-bin/forum.pl?n=3&id=1198510244

GetAsyncKeyState чем лучше?

DirectInput - не хочеться привязывать к директиксу. Да и не работал DI никогда.. а под дельфи так вообще с DX Не работал.


oxffff   (2007-12-24 20:24:00) [13]


> DiamondShark ©   (24.12.07 20:11) [33]
>
> > oxffff ©   (24.12.07 19:52) [31]
>
> Это ты глупый. Не видишь разницы между общим правилом и
> частным случаем.

Частный случай, ты телепат?
Есть правила которых ты не знаешь.
Как раз ты говоришь о частном случае.

> > Это не атомарная операция.
>
> Конечно. Запись байта -- сильно не атомарная операция. ;
> )
> Я поторопился с оценкой "хорошая память". Ты опять забыл,
>  какой массив общий.

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

> > Состояние обновлено частично в момент работы потока чтения.
>
>
> Да. Пол-байта записали. ;)

Ты реально бестолковый дятел.
Увы запись байта атомарна.
А вот состояние всего массива не согласовано.

> > Не видно обновления в потоке чтения, либо видно частично.
>
>
> Булеан значение частично -- это у блондинок.
>
> Ты за весь массив целиком боишься? Зря. Прикладные данные
> в нём такого характера, что это совершенно не критично.

Да ты что? Телепат что ли ты?
Прикинь нажал кнопку, а результата нет.

> > Опять пытаешься съехать.
> Опять твоё воображение.
> Ты почему-то решил, что я давал общий ответ, а не в контексте
> задачи, а потом коварно "съехал".
> Но твои церебральные тараканы -- твоя личная проблема.


Нет, Я это твоя проблема.


Sapersky   (2007-12-24 20:20:00) [14]

Состояние обновлено частично в момент работы потока чтения.
Не видно обновления в потоке чтения, либо видно частично.


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

Пример из MSDN, если это тот, который с
int iValue;
BOOL fValueHasBeenComputed = FALSE;
- относится к порядку записи значений в память.
В данном случае порядок неважен.

GetKeyboardState
An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue.


Обычно GetKeyboardState работает быстрее, чем отлавливание WM_KEYDOWN (т.е. реакция на нажатие кнопок лучше). Здесь же написано, что она фактически привязана к очереди сообщений. Странно...

Также странно и желание автора вопроса использовать GetKeyboardState в отдельном потоке. Неужели в основном не работает?
Как вариант, есть ещё GetAsyncKeyState/DirectInput.


DiamondShark   (2007-12-24 20:18:00) [15]


> @!!ex ©   (24.12.07 20:16) [35]

См. Remarks к функции GetKeyboardState


@!!ex   (2007-12-24 20:16:00) [16]

> Ни точной постановки задачи,  ни твоей реализации нет.

Да как же нет?
Все реализация здесь...
Нужно получить состояние клавиши...
И оно не получается. вот и все.


DiamondShark   (2007-12-24 20:15:00) [17]


> Если ты не понимаешь, что операция установки нового состояния
> для всего массива не атомарна

Весь массив никого не волнует.
Вникай в задачу.
Массив здесь только из соображений удобства доступа. А по задаче -- это 256 независимых булевских переменных.


DiamondShark   (2007-12-24 20:11:00) [18]


> oxffff ©   (24.12.07 19:52) [31]

Это ты глупый. Не видишь разницы между общим правилом и частным случаем.


> Это не атомарная операция.

Конечно. Запись байта -- сильно не атомарная операция. ;)
Я поторопился с оценкой "хорошая память". Ты опять забыл, какой массив общий.


> Состояние обновлено частично в момент работы потока чтения.

Да. Пол-байта записали. ;)


> Не видно обновления в потоке чтения, либо видно частично.

Булеан значение частично -- это у блондинок.

Ты за весь массив целиком боишься? Зря. Прикладные данные в нём такого характера, что это совершенно не критично.


> Опять пытаешься съехать.

Опять твоё воображение.
Ты почему-то решил, что я давал общий ответ, а не в контексте задачи, а потом коварно "съехал".
Но твои церебральные тараканы -- твоя личная проблема.


oxffff   (2007-12-24 19:56:00) [19]


> DiamondShark ©   (24.12.07 19:46) [30]


Ты реально не понимаешь проблемы.
Опять пытаешься съехать.

for Index:=0 to 255 do
  if NewKeys[Index] shr 7 <> OldKeys[Index] shr 7 then
    Keys[Index]:=NewKeys[Index] shr 7 = 1;


Это не атомарная операция.
-> потенциальные проблемы на однопроцессорной машине.
Состояние обновлено частично в момент работы потока чтения.

-> потенциальные проблемы на многопроцессорной машине.
Не видно обновления в потоке чтения, либо видно частично.


oxffff   (2007-12-24 19:52:00) [20]


> DiamondShark ©   (24.12.07 19:44) [29]


Слушай, ты что глупый?

Тебе сказали, что представление памяти для потоков запущенных на разных процессорах в один и тот же момент будет разным.
Если ты не понимаешь, что операция установки нового состояния для всего массива не атомарна, то будут dirty Updates.
Которые могут приводить к проблемам в логике даже на однопроцессорной машине.
На многопроцессорной машине ситуация еще хуще. Ты обновил значения, а другой поток не видит обновления.
А если это критично?


Страницы:   1 2 3

Наверх

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