Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2008.10.26;
Скачать: [xml.tar.bz2];

Вниз

Задачка для совсем-совсем начинающих   Найти похожие ветки 

 
DiamondShark ©   (2008-09-04 14:38) [80]


> oxffff ©   (04.09.08 14:14) [76]

Гоню. За пределы ProcessMessages исключения не выпускаются. ВЦЛ -- сволочь.


> oxffff ©   (04.09.08 14:18) [77]

И чё? Ну вот представь, что у тебя есть код:

while AnyVar do begin
//...
AnyVar := false;
end

После присваивания произошло переключение потоков. Что страшного случилось? Почему в этом случае ты не пишешь интерлокед-функцию, а полагаешься на простое присваивание?

По твоей логике, в этом коде есть вероятность лишней итерации цикла (если AnyVar -- не в регистре, а в пямяти).
Это ж ужас какие глюки должны испытывать обычные приложения в многопроцессорной среде.


 
Slym ©   (2008-09-04 14:42) [81]

Slym ©   (04.09.08 14:33) [79]
применен способ защиты запутыванием условного перехода без применения операторов условного перехода (условности я конечно вырезал т.к. не к месту)


 
oxffff ©   (2008-09-04 14:52) [82]


> Slym ©   (04.09.08 14:33) [79]


Что это чудеса генной инженерии?
Хто такой intercept?
Смысл однако мне понятен.
Только по условию нет возможности править pascal source код.

А твой пример тогда проще сразу переписать.

procedure Proc;
label label1;
begin
ShowMessage("Ïðîöåäóðà Proc ñòàðòîâàëà");
while True do
begin
 //Sleep(1);// Ýòî ÷òîáû íå ãðóçèòü ïðîöåññîð
 goto Label1;
Application.ProcessMessages;
end;
Label1: ShowMessage("Ïðîöåäóðà Proc çàâåðøèëàñü");
end;


 
DiamondShark ©   (2008-09-04 14:56) [83]

procedure TForm1.Button1Click(Sender: TObject);
var
 SaveOnMessage: TMessageEvent;
begin
SaveOnMessage := Application.OnMessage;
Application.OnMessage := OnMessageAbort;
try
 Proc;
finally
  Application.OnMessage := SaveOnMessage;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 PostMessage(0, WM_USER+1, 0, 0);
end;

procedure TForm1.OnMessageAbort(var Msg: TMsg; var Handled: Boolean);
begin
 if (Msg.message = WM_USER+1) and (Msg.hwnd = 0) then Abort;
end;


 
oxffff ©   (2008-09-04 15:02) [84]


> DiamondShark ©   (04.09.08 14:38) [80]
>
> > oxffff ©   (04.09.08 14:14) [76]
>
> Гоню. За пределы ProcessMessages исключения не выпускаются.
>  ВЦЛ -- сволочь.


За пределы ProcessMessages исключения как раз выпускаются.
А вот за пределы WndProc уже нет.
Способы решения [42], [44].


> > oxffff ©   (04.09.08 14:18) [77]
>
> И чё? Ну вот представь, что у тебя есть код:
>
> while AnyVar do begin
> //...
> AnyVar := false;
> end
>
> После присваивания произошло переключение потоков. Что страшного
> случилось? Почему в этом случае ты не пишешь интерлокед-
> функцию, а полагаешься на простое присваивание?
>
> По твоей логике, в этом коде есть вероятность лишней итерации
> цикла (если AnyVar -- не в регистре, а в пямяти).
> Это ж ужас какие глюки должны испытывать обычные приложения
> в многопроцессорной среде.


Да действительно, в данном конкретном случае может быть несколько лишних итерация цикла. Но для кого то это может быть смертельно, я брать ситуацию в общем.
Однако приучать стоит себя уже сейчас.
Поскольку мы в большинстве своем пока привыкли писать программы где цикл обработки сообщений использует один поток для своей работы и один процессор. Однако уже сейчас в спешном порядке нужно перестраивать свое мышление.


 
oxffff ©   (2008-09-04 15:14) [85]


> DiamondShark ©   (04.09.08 14:56) [83]


Хитрый жук. :)
Все таки исхитрился сгенерировать исключение в ProcessMessage.
Тоже интересный вариант.


 
Slym ©   (2008-09-04 15:30) [86]

Intercept(Sleep,MySleep);
это сплайсинг... подмена оригинального Sleep собственным MySleep например через таблицу импорта
т.е. до сплайсинга официально спим... после сплайсинга переход


 
Slym ©   (2008-09-04 15:31) [87]

oxffff ©   (04.09.08 14:52) [82]
Только по условию нет возможности править pascal source код.

да ради бога... поставил хук, внедрился в ап жертвы, сделал сплайсинг слипа... и все из внешнего процесса


 
DiamondShark ©   (2008-09-04 15:42) [88]


> oxffff ©   (04.09.08 15:02) [84]
> За пределы ProcessMessages исключения как раз выпускаются.
>  
> А вот за пределы WndProc уже нет.

Угу.


> oxffff ©   (04.09.08 15:14) [85]
> > DiamondShark ©   (04.09.08 14:56) [83]
> Хитрый жук. :)

Да просто в исходники посмотрел.


> oxffff ©   (04.09.08 15:02) [84]
> Да действительно, в данном конкретном
> случае может быть несколько лишних итерация цикла.

Как страшно жить. Хорошо, что реальность не соответствует некоторым апокалиптическим представлениям о ней.


> Поскольку мы в большинстве своем пока привыкли писать программы
> где цикл обработки сообщений использует один поток для своей
> работы и один процессор.

При чём здесь цикл сообщений? В моём коде вообще нет ни намёка на сообщения, однако, по-твоему получается, что на многопроцессорной машине его может жестого сглючить. И не только этот код, но и вообще, любой код, содержащий неатомарные операции с памятью. Учитывая, что любой нормальный код из таких операций состоит чуть менее, чем полностью, работоспособных на многопроцессорных системах программ не должно существовать в природе.
Тем не менее, это не так.


> Однако уже сейчас в спешном порядке нужно перестраивать
> свое мышление.

Скажи нет операциям a:=b+c
Тут в одной строчке целых три потенциальных глюка.


 
Slym ©   (2008-09-04 16:08) [89]

полная версия хака:
uses TlHelp32;

procedure Proc;
begin
 ShowMessage("Процедура Proc стартовала");
 while True do
 begin
   Sleep(1); // Это чтобы не грузить процессор
   Application.ProcessMessages;
 end;
 ShowMessage("Процедура Proc завершилась");
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Proc;
end;

type
 PImageImportDescriptor = ^TImageImportDescriptor;
 IMAGE_IMPORT_DESCRIPTOR = packed record
 case Integer of
   0: (Characteristics: DWORD);
   1: (OriginalFirstThunk: DWORD;
       TimeDateStamp: DWORD;
       ForwarderChain: DWORD;
       Name: DWORD;
       FirstThunk: DWORD);
 end;
 TImageImportDescriptor = IMAGE_IMPORT_DESCRIPTOR;
 PFARPROC = ^FARPROC;

const ImagehlpLib = "IMAGEHLP.DLL";

function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;
 DirectoryEntry: Word; var Size: ULONG): Pointer; stdcall; external ImagehlpLib
   name "ImageDirectoryEntryToData";

procedure ReplaceIATEntryInModule(pszCallerModName: Pchar; pfnCurrent, pfnNew: FarProc; hmodCaller: hModule);
var
 ulSize: ULONG;
 pImportDesc: PImageImportDescriptor;
 ppfn: PFARPROC;
 vp,written:DWORD;
begin
 pImportDesc := ImageDirectoryEntryToData(Pointer(hmodCaller), TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, ulSize);
 if pImportDesc = nil then exit;
 while pImportDesc.Name <> 0 do
 begin
   if (lstrcmpiA(PChar(hmodCaller+pImportDesc.Name), pszCallerModName) = 0) then
   begin
     ppfn := PFARPROC(hmodCaller + pImportDesc.FirstThunk);
     while ppfn^ <> nil do
     begin
       if ppfn^=pfnCurrent then
       begin
         Win32Check(VirtualProtectEx(GetCurrentProcess, ppfn, SizeOf(pointer), PAGE_EXECUTE_READWRITE, @vp));
         Win32Check(WriteProcessMemory(GetCurrentProcess, ppfn, @pfnNew, sizeof(pfnNew), Written));
         Win32Check(VirtualProtectEx(GetCurrentProcess, ppfn, SizeOf(pointer), vp, @vp));
       end;
       Inc(ppfn);
     end;
   end;
   Inc(pImportDesc);
 end;
end;

procedure ReplaceIATEntryInAllModules(pszCallerModName: Pchar; pfnCurrent, pfnNew: FarProc);
var
 hSnapShot: THandle;
 me32: MODULEENTRY32;
begin
 hSnapShot:=CreateToolHelp32SnapShot(TH32CS_SNAPMODULE, GetCurrentProcessId);
 if hSnapshot = INVALID_HANDLE_VALUE then RaiseLastOSError;
 try
   ZeroMemory(@me32, sizeof(MODULEENTRY32));
   me32.dwSize := sizeof(MODULEENTRY32);
   Module32First(hSnapShot, me32);
   repeat
     ReplaceIATEntryInModule(pszCallerModName, pfnCurrent, pfnNew, me32.hModule);
   until not Module32Next(hSnapShot, me32);
 finally
   CloseHandle(hSnapShot);
 end;
end;

procedure Intercept(const ModuleName,ProcName:string;const NewProc:FarProc);overload;
var OldProc:FarProc;
begin
 OldProc := GetProcAddress(GetModuleHandle(PChar(ModuleName)), PChar(ProcName));
 ReplaceIATEntryInAllModules(PChar(ModuleName), OldProc, NewProc);
end;

procedure MySleep;
asm
pop EAX
add EAX, 14
pop EDX
push eax
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Intercept("kernel32.dll","Sleep",@Mysleep);
end;


 
Игорь Шевченко ©   (2008-09-04 16:11) [90]

народ, а вот если эта...сумму чисел в массиве надо посчитать, ну или там матрицу транспонировать...?

Оно как по-правильному, ась ?


 
oxffff ©   (2008-09-04 16:19) [91]


> DiamondShark ©   (04.09.08 15:42) [88]
>
> > oxffff ©   (04.09.08 15:02) [84]
> > За пределы ProcessMessages исключения как раз выпускаются.
>
> >  
> > А вот за пределы WndProc уже нет.
>
> Угу.


Дык, я тебя поправил.


>
>
> > oxffff ©   (04.09.08 15:14) [85]
> > > DiamondShark ©   (04.09.08 14:56) [83]
> > Хитрый жук. :)
>
> Да просто в исходники посмотрел.
>


Вот за это молодец!!!


>
> > oxffff ©   (04.09.08 15:02) [84]
> > Да действительно, в данном конкретном
> > случае может быть несколько лишних итерация цикла.
>
> Как страшно жить. Хорошо, что реальность не соответствует
> некоторым апокалиптическим представлениям о ней.
>
>
> > Поскольку мы в большинстве своем пока привыкли писать
> программы
> > где цикл обработки сообщений использует один поток для
> своей
> > работы и один процессор.
>
> При чём здесь цикл сообщений? В моём коде вообще нет ни
> намёка на сообщения, однако, по-твоему получается, что на
> многопроцессорной машине его может жестого сглючить. И не
> только этот код, но и вообще, любой код, содержащий неатомарные
> операции с памятью. Учитывая, что любой нормальный код из
> таких операций состоит чуть менее, чем полностью, работоспособных
> на многопроцессорных системах программ не должно существовать
> в природе.
> Тем не менее, это не так.
>
>
> > Однако уже сейчас в спешном порядке нужно перестраивать
>
> > свое мышление.
>
> Скажи нет операциям a:=b+c
> Тут в одной строчке целых три потенциальных глюка.


А что есть гарантия, что переключении когерентность кэшей гарантирована?
Может просто SetProcessAffinityMask у процесса стоит на один процессор.

А если SetProcessAffinityMask


 
Andy BitOff ©   (2008-09-04 17:02) [92]

> Slym ©   (04.09.08 16:08) [89]

Как страшно жить.


 
DiamondShark ©   (2008-09-04 17:38) [93]


> А что есть гарантия, что переключении когерентность кэшей
> гарантирована?

Вообще-то, когерентность кэшей в SMP-архитектуре обеспечивается аппаратно.


 
Dmitry S ©   (2008-09-04 17:44) [94]


> oxffff ©

Ты еще синхронизацию устрой :)

Программа вообще ничего не знает о процессорах. Для нее есть потоки. А то приложение из одной формы и пары кнопок выполняется в одном потоке -> о какой синхронизации речь?


 
Leonid Troyanovsky ©   (2008-09-04 18:33) [95]


> Игорь Шевченко ©   (04.09.08 16:11) [90]

>  ну или там матрицу транспонировать...?

Ну, дай орлам хоть слегка, но парить.

--
Regards, LVT.


 
McSimm ©   (2008-09-04 18:55) [96]


> McSimm ©   (04.09.08 09:53) [40]
> > Кстати твое решение правильнее написать так.
> > InterlockedExchange(@FFlag,0);
>
> Зачем это здесь ?

> oxffff ©   (04.09.08 10:01) [41]
> Во первых при работе на многопроцессорных машинах.
> При переключении кэш другого процессора может не обновиться,
>  и утрируя может получится ситуация, когда вы нажали на
> кнопку, а результат не мгновенный.
>
> Однако сейчас ситуация усложняется тем, что есть тенденция
>  делать обработку сообщений параллельно. Соответственно
> разные процессоры(ядра) могут не вовремя увидеть изменения.
>  И будут задержки.
>
> P.S. Готовь мозг к параллельным вычислениям с молоду.
>


Что-то ерунда какая-то.

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

Или я правда пропустил так много изменений за два года отлучения от программирования под Win32 ?


 
Slym ©   (2008-09-05 05:22) [97]

oxffff ©   (04.09.08 10:01) [41]
P.S. Готовь мозг к параллельным вычислениям с молоду.

с этим согласен... не согласен с тем что нужно извращаться в полностью линейном вычислении... Это плодит ошибки и неразбериху
Код должен быть простым и без оглядки на многопоточность/процессорность... а вот доступ к шареным объектам - это отдельная проблема и решаться она должна локально и желательно самим объектом согласно ООП


 
MemoryLeak   (2008-09-05 07:34) [98]

oxffff ©   (03.09.08 23:35) [12]
Практическое применение, пример ?

P.S. Это тебе встречная задачка.


 
Slym ©   (2008-09-05 07:37) [99]

MemoryLeak   (05.09.08 7:34) [98]
например яма в ветке защиты ПО... и вылезти из ямы - обойти эту ветку защиты


 
oxffff ©   (2008-09-05 09:19) [100]


> MemoryLeak   (05.09.08 07:34) [98]
> oxffff ©   (03.09.08 23:35) [12]
> Практическое применение, пример ?
>
> P.S. Это тебе встречная задачка


А если подумать?


 
Slym ©   (2008-09-05 09:26) [101]

oxffff ©   (05.09.08 9:19) [100]
так ты не ответил про мое решение... канает?


 
oxffff ©   (2008-09-05 09:56) [102]


> DiamondShark ©   (04.09.08 17:38) [93]
>
> > А что есть гарантия, что переключении когерентность кэшей
>
> > гарантирована?
>
> Вообще-то, когерентность кэшей в SMP-архитектуре обеспечивается
> аппаратно


Но ведь есть же маленькая глава в MSDN.
Synchronization and Multiprocessor Issues.

Сейчас перечитаю

CHAPTER 18 CACHING, PIPELINING AND BUFFERING

Description
Writes back all modified cache lines in the processor’s internal cache to main memory and invalidates
(flushes) the internal caches. The instruction then issues a special-function bus cycle that
directs external caches to also write back modified data and another bus cycle to indicate that
the external caches should be invalidated.

P.S. Есть подозрение, что возможно планировщик на многопроцессорном тачке, использует WBINVD—Write Back and Invalidate Cache.
Поэтому при переключении данного потока на другой проц все будет зашибись

Чую, что здесь прогнал я.  :)


 
oxffff ©   (2008-09-05 10:12) [103]


> Slym ©   (05.09.08 09:26) [101]
> oxffff ©   (05.09.08 9:19) [100]
> так ты не ответил про мое решение... канает?


Конечно канает, ведь работает же. :)



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

Форум: "Прочее";
Текущий архив: 2008.10.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.66 MB
Время: 0.011 c
2-1221648561
renex
2008-09-17 14:49
2008.10.26
вызов функции из другого модуля


15-1220412091
Slider007
2008-09-03 07:21
2008.10.26
С днем рождения ! 3 сентября 2008 среда


2-1221833104
Alexei
2008-09-19 18:05
2008.10.26
Запуск приложения


9-1174567977
Maximillian
2007-03-22 15:52
2008.10.26
Делаю игру, нужна помощь по скроллингу


15-1220002367
начинающий
2008-08-29 13:32
2008.10.26
Windows Vista





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский