Форум: "Начинающим";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
ВнизВопрос про многопоточность. Найти похожие ветки
← →
@!!ex © (2007-12-24 18:46) [0]Чем грозит такая ситуация:
есть boolean массив.
есть дополнительный поток, который постоянно перебирается все элементы массива и меняет их значения.
Из основного потока периодически берутся значения массива.
Никакой синхронизации нет...
← →
oxffff © (2007-12-24 18:55) [1]
> @!!ex © (24.12.07 18:46)
А как ты меняешь значения?
← →
@!!ex © (2007-12-24 18:56) [2]
procedure TKeys.Update;
var
Index:integer;
begin
GetKeyboardState(NewKeys);
for Index:=0 to 255 do
if NewKeys[Index] shr 7 <> OldKeys[Index] shr 7 then
Keys[Index]:=NewKeys[Index] shr 7 = 1;
CopyMemory(@OldKeys[0],@NewKeys[0],256);
end;
Я думаю может работать с отдельным массивом, а потом его копировать в основной?
ТОгда замена каждого жэлемента будет атомарной операцией?
← →
oxffff © (2007-12-24 18:58) [3]
> @!!ex © (24.12.07 18:46)
Если просто меняешь,то на многопроцессорных машинах потенциально это может стать причиной некорретного поведения.
Решение использование InterlockedExchange
← →
oxffff © (2007-12-24 19:00) [4]
> @!!ex © (24.12.07 18:56) [2]
Открой SDK см. раздел Synchronization
Synchronization and Multiprocessor Issues
← →
DiamondShark © (2007-12-24 19:02) [5]Если главный поток только читает, а пишет только один доп. поток, то ничего страшного не произойдёт.
← →
oxffff © (2007-12-24 19:02) [6]
> @!!ex © (24.12.07 18:56) [2]
Решение - это обеспечение когерентности кэшей процессоров.
← →
@!!ex © (2007-12-24 19:02) [7]> Если просто меняешь,то на многопроцессорных машинах потенциально
> это может стать причиной некорретного поведения.
тоесть там может читаться в тоже время, когда писаться?
← →
oxffff © (2007-12-24 19:02) [8]
> DiamondShark © (24.12.07 19:02) [5]
Читай мат. часть.
← →
@!!ex © (2007-12-24 19:04) [9]AV быть может или нет в данной ситуации?
Или это грозит только некорректностью данных?
← →
oxffff © (2007-12-24 19:05) [10]
> @!!ex © (24.12.07 19:02) [7]
Представление памяти потоков запущенных на разных процессорах будет разным.
Memory Caching
When a processor writes to a memory location, the value is cached to improve performance. Similarly, the processor attempts to satisfy read requests from the cache to improve performance. Furthermore, processors begin to fetch values from memory before they are requested by the application. This can happen as part of speculative execution or due to cache line issues.
← →
oxffff © (2007-12-24 19:06) [11]
> @!!ex © (24.12.07 19:04) [9]
Это грозит только некорретностью данных, которое может привести к AV. :)
← →
@!!ex © (2007-12-24 19:07) [12]> [11] oxffff © (24.12.07 19:06)
Вобщем я понял. :)
К счастью, нашлось решение, которое убирает необходимость в двух потоках...
УРА! :)))
← →
DiamondShark © (2007-12-24 19:13) [13]
> oxffff © (24.12.07 19:02) [8]
>
> > DiamondShark © (24.12.07 19:02) [5]
>
> Читай мат. часть.
Читай условия, попугайчик. А то память у тебя хорошая, а соображения -- ноль.
← →
oxffff © (2007-12-24 19:16) [14]
> DiamondShark © (24.12.07 19:13) [13]
Хавальничек свой прикрыл бы, дружок.
И прочитал бы внимательно сам.
Условия: один поток пишет ( CopyMemory(@OldKeys[0],@NewKeys[0],256); )
другой поток читает.
← →
@!!ex © (2007-12-24 19:20) [15]> [14] oxffff © (24.12.07 19:16)
Не. Общие данные - массив Keys.
← →
oxffff © (2007-12-24 19:26) [16]
> @!!ex © (24.12.07 19:20) [15]
O. :)
Ну разницы особой нет.
Основное, что это не инструкции с lock префиксом.
← →
DiamondShark © (2007-12-24 19:26) [17]
> oxffff © (24.12.07 19:16) [14]
Глупышка. Ты даже не въехал, какой массив совместно используется.
← →
oxffff © (2007-12-24 19:29) [18]
> DiamondShark © (24.12.07 19:26) [17]
Ну не беда. Меня поправили.
И ты даже не понял о чем говорил. Это печальнее. :)
← →
DiamondShark © (2007-12-24 19:30) [19]
> oxffff © (24.12.07 19:26) [16]
В контекст задачи ты тоже не въехал: в то, что элементы массива примитивного типа, в то, какой смысл имеют значения элементов массива.
Ты себе голову цитатами набил -- тебе достаточно.
← →
oxffff © (2007-12-24 19:32) [20]
> DiamondShark © (24.12.07 19:26) [17]
Ну тем не менее я ответил на вопрос автора
Чем грозит такая ситуация
А ты вякяешь без доказательств.
P.S. А твои оскорбления говорят о том, что увы больше ты ничего не знаешь.
← →
@!!ex © (2007-12-24 19:32) [21]oxffff, DiamondShark - расслабьтесь.
← →
@!!ex © (2007-12-24 19:33) [22]Лучше расскажите, почему не работает?
GetKeyboardState(NewKeys);
for Index:=0 to 255 do
if NewKeys[Index] shr 7 <> OldKeys[Index] shr 7 then
Keys[Index]:=NewKeys[Index] shr 7 = 1;
CopyMemory(@OldKeys[0],@NewKeys[0],256);
Вынес в обработку мультимедийного таймера.
TimerID:=timeSetEvent(16,0,@TimerProc,0,TIME_PERIODIC);
Keys всегда содержит false....
← →
trubin © (2007-12-24 19:34) [23]To модератор:
на ветку пора замок вешать
← →
oxffff © (2007-12-24 19:36) [24]
> DiamondShark © (24.12.07 19:30) [19]
Я то все понял.
А ты пытаешь съехать сваливая на незначимость Shared Data.
А мои ответы конкретно касаются случая для многопроцессорных машин.
Рекомендую тебе заглянуть в SDK.
Там достаточно хороший пример.
← →
oxffff © (2007-12-24 19:39) [25]
> @!!ex © (24.12.07 19:33) [22]
Я не телепат.
← →
@!!ex © (2007-12-24 19:40) [26]> [25] oxffff © (24.12.07 19:39)
идей нет?
← →
oxffff © (2007-12-24 19:40) [27]
> DiamondShark © (24.12.07 19:30) [19]
Похоже ты завидуешь.
← →
oxffff © (2007-12-24 19:42) [28]
> @!!ex © (24.12.07 19:40) [26]
Идеи?
Повторяю я не телепат.
Ни точной постановки задачи, ни твоей реализации нет.
← →
DiamondShark © (2007-12-24 19:44) [29]
> oxffff © (24.12.07 19:40) [27]
>
> > DiamondShark © (24.12.07 19:30) [19]
>
>
> Похоже ты завидуешь.
:))))))
Чему? Умению цитировать МСДН? С этим справится не слишком сложный бот, настроеный на ключевые слова.
← →
DiamondShark © (2007-12-24 19:46) [30]
> @!!ex © (24.12.07 19:40) [26]
> > [25] oxffff © (24.12.07 19:39)
>
> идей нет?
Просто он ещё не добрался до нужной страницы SDK ;)
А там написано вот что:
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. The status does not change as keyboard messages are posted to the thread"s message queue, nor does it change as keyboard messages are posted to or retrieved from message queues of other threads. (Exception: Threads that are connected through AttachThreadInput share the same keyboard state.)
← →
oxffff © (2007-12-24 19:52) [31]
> DiamondShark © (24.12.07 19:44) [29]
Слушай, ты что глупый?
Тебе сказали, что представление памяти для потоков запущенных на разных процессорах в один и тот же момент будет разным.
Если ты не понимаешь, что операция установки нового состояния для всего массива не атомарна, то будут dirty Updates.
Которые могут приводить к проблемам в логике даже на однопроцессорной машине.
На многопроцессорной машине ситуация еще хуще. Ты обновил значения, а другой поток не видит обновления.
А если это критично?
← →
oxffff © (2007-12-24 19:56) [32]
> 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;
Это не атомарная операция.
-> потенциальные проблемы на однопроцессорной машине.
Состояние обновлено частично в момент работы потока чтения.
-> потенциальные проблемы на многопроцессорной машине.
Не видно обновления в потоке чтения, либо видно частично.
← →
DiamondShark © (2007-12-24 20:11) [33]
> oxffff © (24.12.07 19:52) [31]
Это ты глупый. Не видишь разницы между общим правилом и частным случаем.
> Это не атомарная операция.
Конечно. Запись байта -- сильно не атомарная операция. ;)
Я поторопился с оценкой "хорошая память". Ты опять забыл, какой массив общий.
> Состояние обновлено частично в момент работы потока чтения.
Да. Пол-байта записали. ;)
> Не видно обновления в потоке чтения, либо видно частично.
Булеан значение частично -- это у блондинок.
Ты за весь массив целиком боишься? Зря. Прикладные данные в нём такого характера, что это совершенно не критично.
> Опять пытаешься съехать.
Опять твоё воображение.
Ты почему-то решил, что я давал общий ответ, а не в контексте задачи, а потом коварно "съехал".
Но твои церебральные тараканы -- твоя личная проблема.
← →
DiamondShark © (2007-12-24 20:15) [34]
> Если ты не понимаешь, что операция установки нового состояния
> для всего массива не атомарна
Весь массив никого не волнует.
Вникай в задачу.
Массив здесь только из соображений удобства доступа. А по задаче -- это 256 независимых булевских переменных.
← →
@!!ex © (2007-12-24 20:16) [35]> Ни точной постановки задачи, ни твоей реализации нет.
Да как же нет?
Все реализация здесь...
Нужно получить состояние клавиши...
И оно не получается. вот и все.
← →
DiamondShark © (2007-12-24 20:18) [36]
> @!!ex © (24.12.07 20:16) [35]
См. Remarks к функции GetKeyboardState
← →
Sapersky (2007-12-24 20:20) [37]Состояние обновлено частично в момент работы потока чтения.
Не видно обновления в потоке чтения, либо видно частично.
Так и фиг с ним. Это же проверка нажатия клавиш. На этом цикле не увидится - на следующем дойдёт. А нажать так, чтобы за один цикл всё пролетело, ни один юзер не сможет.
Пример из 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.
← →
oxffff © (2007-12-24 20:24) [38]
> DiamondShark © (24.12.07 20:11) [33]
>
> > oxffff © (24.12.07 19:52) [31]
>
> Это ты глупый. Не видишь разницы между общим правилом и
> частным случаем.
Частный случай, ты телепат?
Есть правила которых ты не знаешь.
Как раз ты говоришь о частном случае.
> > Это не атомарная операция.
>
> Конечно. Запись байта -- сильно не атомарная операция. ;
> )
> Я поторопился с оценкой "хорошая память". Ты опять забыл,
> какой массив общий.
Массив общий только его состояние будет не согласовано.
Нажал кнопку, а результат позже чем ты ожидаешь.
> > Состояние обновлено частично в момент работы потока чтения.
>
>
> Да. Пол-байта записали. ;)
Ты реально бестолковый дятел.
Увы запись байта атомарна.
А вот состояние всего массива не согласовано.
> > Не видно обновления в потоке чтения, либо видно частично.
>
>
> Булеан значение частично -- это у блондинок.
>
> Ты за весь массив целиком боишься? Зря. Прикладные данные
> в нём такого характера, что это совершенно не критично.
Да ты что? Телепат что ли ты?
Прикинь нажал кнопку, а результата нет.
> > Опять пытаешься съехать.
> Опять твоё воображение.
> Ты почему-то решил, что я давал общий ответ, а не в контексте
> задачи, а потом коварно "съехал".
> Но твои церебральные тараканы -- твоя личная проблема.
Нет, Я это твоя проблема.
← →
@!!ex © (2007-12-24 20:24) [39]> Также странно и желание автора вопроса использовать GetKeyboardState
> в отдельном потоке. Неужели в основном не работает?
> Как вариант, есть ещё GetAsyncKeyState/DirectInput.
http://delphimaster.net/view/15-1198510244/
GetAsyncKeyState чем лучше?
DirectInput - не хочеться привязывать к директиксу. Да и не работал DI никогда.. а под дельфи так вообще с DX Не работал.
← →
oxffff © (2007-12-24 20:26) [40]
> Sapersky (24.12.07 20:20) [37]
А если прикинь нажал кнопку, а результата нет.
Так что увы это критично.
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
Память: 0.62 MB
Время: 0.007 c