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

Вниз

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

 
Юрий Зотов ©   (2008-09-03 22:46) [0]

Программистов прошу не подсказывать!!!

Есть такая процедура:

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


Задание: одной кнопкой вызвать процедуру Proc с параметром True,  другой кнопкой завершить ее. Менять код процедуры нельзя.


 
@!!ex ©   (2008-09-03 22:49) [1]

Первые пять секунд после прочтения сообщения я с нарастающией скоростью падал в своих глазах...
потом дошло. :))


 
oxffff ©   (2008-09-03 22:54) [2]


>  другой кнопкой завершить ее.


Power?


 
@!!ex ©   (2008-09-03 23:04) [3]

procedure Start()
var
 T:boolean;
begin
 T:=true;
 Proc(T);
end;

procedure Stop();
begin
 Application.Terminate();
end;

Хотя это не то, что имелось ввиду, но условию задачи не противоречит. :)


 
antonn ©   (2008-09-03 23:05) [4]

и прервется? :)


 
antonn ©   (2008-09-03 23:06) [5]

halt


 
Zeqfreed ©   (2008-09-03 23:08) [6]

Если бросить исключение в Sleep или Application.ProcessMessages это считается «выходом»? :)


 
antonn ©   (2008-09-03 23:09) [7]

var T:boolean;

procedure TForm1.Button1Click(Sender: TObject);
begin
T:=true;
if(sender as TButton).Tag=2 then begin
  t:=false;
end else
Proc(T);
end;

расставить tag по вкусу, назначить один обработчик :)
это есть не нравится вылет приложения :)


 
Tricky   (2008-09-03 23:12) [8]

Вместо sleep(1) нужно поставить SwitchToThread. Так корректнее.


 
Tricky   (2008-09-03 23:13) [9]

Иначе дофигища ресурсов тратится. На каждый слип уходит примерно под 1000 тактов..


 
turbouser ©   (2008-09-03 23:15) [10]

var
 Form1: TForm1;
 FFlag:boolean;
implementation

{$R *.dfm}

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

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

procedure TForm1.Button2Click(Sender: TObject);
begin
 FFlag:=False;
end;


 
easy ©   (2008-09-03 23:19) [11]

просили же не подсказывать, едрен батон..
а тут код вывалили
шоб в начинающих так отвечали..


 
oxffff ©   (2008-09-03 23:35) [12]

я предлагаю усложнить задачу.
До

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

на одной кнопке запуск
на второй корретный выход.

P.S. Идеи кое какие на этот счет имеются, но до конца пока не довел.


 
oxffff ©   (2008-09-03 23:38) [13]


> turbouser ©   (03.09.08 23:15) [10]


Кстати твое решение правильнее написать так.

procedure TForm1.Button2Click(Sender: TObject);
begin
InterlockedExchange(@FFlag,0);
end;


 
Tricky   (2008-09-03 23:45) [14]


> Кстати твое решение правильнее написать так.


Тогда переменная должна быть объявлена как LongBool а не Boolean.


 
Tricky   (2008-09-03 23:46) [15]


> Тогда переменная должна быть объявлена как LongBool а не
> Boolean.

Иначе попадешь на AV.


 
oxffff ©   (2008-09-03 23:55) [16]


> Tricky   (03.09.08 23:45) [14]


Замечание действительное верное. Спасибо.


 
oxffff ©   (2008-09-03 23:56) [17]


> oxffff ©   (03.09.08 23:35) [12]
> я предлагаю усложнить задачу.
> До


Завтра на работе доведу до конца. А сейчас иду спать.


 
oxffff ©   (2008-09-03 23:56) [18]


> oxffff ©   (03.09.08 23:35) [12]
> я предлагаю усложнить задачу.
> До


Завтра на работе доведу до конца. А сейчас иду спать.


 
antonn ©   (2008-09-04 00:04) [19]


> просили же не подсказывать, едрен батон..
> а тут код вывалили
> шоб в начинающих так отвечали..
>

попросили программистов не подсказывать. мне тут недавно посоветовали пойти дельфи поучить и годика через три возвращаться, так что ко мне никаких претензий - я начинающий.


 
{RASkov} ©   (2008-09-04 00:07) [20]

Ветка действительно интересная и поучительная, по крайней мере начало было таким, но все испоритили :(
Хотя с другой стороны, как можно определить(отличить) совсем-совсем начинающего от не совсем....
А так antonn и turbouser присвоили себе статус того, для кого эта задачка была?(вопрос) :)


 
{RASkov} ©   (2008-09-04 00:08) [21]

> [19] antonn ©   (04.09.08 00:04)
> я начинающий.

совсем-совсем? :)
Чем докажешь? Задачу ведь решил...
:о)


 
oxffff ©   (2008-09-04 00:08) [22]


> {RASkov} ©   (04.09.08 00:07) [20]


Есть задачка в [12].
Для кого она?


 
{RASkov} ©   (2008-09-04 00:10) [23]

> [22] oxffff ©   (04.09.08 00:08)
> Для кого она?

Для извращенцев? :)


 
oxffff ©   (2008-09-04 00:11) [24]

Для головоломов. :)


 
oxffff ©   (2008-09-04 00:14) [25]

Ксатити я еще одно решение придумал для [12]. Не теперь точно спать. :)))))


 
Tricky   (2008-09-04 00:16) [26]


> Для головоломов. :)


Для каких головоломов нафиг.. Ставится try Except в этот метод, затем обрабатываем какое нибудь Custom сообщение (вне этого метода) и если это оно (наше сообщение) делаем raise (соответственно выход на строке ProcessMessages), и выходим спокойно из цикла. По другому никак не выйдет, думай не думай.


 
antonn ©   (2008-09-04 00:20) [27]


> Чем докажешь? Задачу ведь решил...
> :о)

мнение авторитета не обсуждается, сказано - учить три года, значит начинающий :)
или так - :(


 
{RASkov} ©   (2008-09-04 00:36) [28]

> [27] antonn ©   (04.09.08 00:20)
> значит начинающий :)

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


 
{RASkov} ©   (2008-09-04 00:45) [29]

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

Чёт жестоко как-то.)
Получается, лучше вообще не отвечать кем бы то не был... :)
С другой стороны тут не ответ нужен, а начинающему самому попробывать решить данную задачу(просто для себя) и не хвалится ответом в данной ветке....


 
Германн ©   (2008-09-04 00:50) [30]


> easy ©   (03.09.08 23:19) [11]
>  ...
> шоб в начинающих так отвечали..
>

Шоб в начинающих так спрашивали!


 
KilkennyCat ©   (2008-09-04 08:22) [31]

А я не понял вопроса...


 
brother ©   (2008-09-04 08:38) [32]

а зачем эта задачка? я не понял, что она должна показать?


 
oxffff ©   (2008-09-04 09:11) [33]


> Tricky   (04.09.08 00:16) [26]
>
> > Для головоломов. :)
>
>
> Для каких головоломов нафиг.. Ставится try Except в этот
> метод, затем обрабатываем какое нибудь Custom сообщение
> (вне этого метода) и если это оно (наше сообщение) делаем
> raise (соответственно выход на строке ProcessMessages),
> и выходим спокойно из цикла. По другому никак не выйдет,
>  думай не думай.


Во первых так не получится.

Увы нафиг так не получится.
Даже, если ты поставишь try except в метод [12] (чего по условию задачи делать нельзя. А именно нельзя менять код [12]. Ну да ладно игнорируем это правило) и сгенерируешь исключение в user message handler, то proc об этом не узнает.
И в try except свой нафиг не попадешь.

Но напоминаю, что задача при нажатии на вторую кнопку покинуть  proc.

>По другому никак не выйдет, думай не думай.

Думай. Думай.


 
Skyle ©   (2008-09-04 09:13) [34]


> oxffff ©   (04.09.08 09:11) [33]


> >По другому никак не выйдет, думай не думай.
>
> Думай. Думай.

А что думать, ответ уже в ветке дали :(


 
oxffff ©   (2008-09-04 09:13) [35]

>oxffff ©   (04.09.08 09:11) [33]

Кнопки естественно не на чистом API, а VCL обертках.


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


> Skyle ©   (04.09.08 09:13) [34]


Дык, уже новая задача в см [12].


 
brother ©   (2008-09-04 09:16) [37]

> Дык, уже новая задача в см

новая то она новая, только реализация ее будет через одно место, тк это не стандартный подход к тз


 
oxffff ©   (2008-09-04 09:18) [38]


> brother ©   (04.09.08 09:16) [37]


Ты уже знаешь решение?


 
brother ©   (2008-09-04 09:21) [39]

понятия не имею, но судя из исходных данных, точно через одно место...


 
McSimm ©   (2008-09-04 09:53) [40]


> Кстати твое решение правильнее написать так.
>
> InterlockedExchange(@FFlag,0);

Зачем это здесь ?


 
oxffff ©   (2008-09-04 10:01) [41]


> McSimm ©   (04.09.08 09:53) [40]


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

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

P.S. Готовь мозг к параллельным вычислениям с молоду.


 
Rouse_ ©   (2008-09-04 10:17) [42]


> я предлагаю усложнить задачу.
> До

Эмнь... извращение конечно, но :)

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

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

procedure WritePtrData(const Data: Word);
var
 NopAddr: PBYTE;
 Dumme: DWORD;
begin
 NopAddr := @Proc;
 Inc(NopAddr, 29);
 WriteProcessMemory(GetCurrentProcess, NopAddr, @Data, 2, Dumme);
end;

procedure TimerProc(hend: THandle; uMsg: UINT;
 idEvent: UINT_PTR; dwTime: DWORD); stdcall;
begin
 KillTimer(0, idEvent);
 WritePtrData($EBEB);
end;

procedure TForm5.Button2Click(Sender: TObject);
begin
 WritePtrData($9090);
 SetTimer(0, 0, 50, @TimerProc);
end;


 
brother ©   (2008-09-04 10:20) [43]

> procedure WritePtrData(const Data: Word);
> var
> NopAddr: PBYTE;
> Dumme: DWORD;
> begin
> NopAddr := @Proc;
> Inc(NopAddr, 29);
> WriteProcessMemory(GetCurrentProcess, NopAddr, @Data, 2,
> Dumme);
> end;
>
> procedure TimerProc(hend: THandle; uMsg: UINT;
> idEvent: UINT_PTR; dwTime: DWORD); stdcall;
> begin
> KillTimer(0, idEvent);
> WritePtrData($EBEB);
> end;
>
> procedure TForm5.Button2Click(Sender: TObject);
> begin
> WritePtrData($9090);
> SetTimer(0, 0, 50, @TimerProc);
> end;

вот про это я и говорил.... лезем в память, и понеслась! )


 
oxffff ©   (2008-09-04 10:23) [44]


> Rouse_ ©   (04.09.08 10:17) [42]


:)

Да это одно из решений.
Именно он нем я написал в oxffff ©   (04.09.08 00:14) [25].

:)

А первое решение такое.

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

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

{НУ это можно конечно сократить. }

procedure TForm1.Button2Click(Sender: TObject);
begin
asm
mov eax,fs:[0];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov eax,[eax];
mov fs:[0],eax;
end;
RaiseException(0,0,0,nil);
end;


 
Игорь Шевченко ©   (2008-09-04 10:26) [45]

офигеть какие начинающие. воистину - фичи ради фич


 
Ega23 ©   (2008-09-04 10:27) [46]


> Задание: одной кнопкой вызвать процедуру Proc с параметром
> True,  другой кнопкой завершить ее. Менять код процедуры
> нельзя.


Дык параметр-то - var...  :)


 
oxffff ©   (2008-09-04 10:28) [47]


> Ega23 ©   (04.09.08 10:27) [46]


Там уже нет параметра. Внимательно [12].


 
Медвежонок Пятачок ©   (2008-09-04 10:31) [48]

Ой блииииин, ну вы и тормоза.....
:)


 
Медвежонок Пятачок ©   (2008-09-04 10:32) [49]

Можно я прикинусь не программистом и приведу решение?


 
brother ©   (2008-09-04 10:36) [50]

давай!


 
Медвежонок Пятачок ©   (2008-09-04 10:37) [51]

В [3] почти правильное решение.

Только одна процедура лишняя и один параметр задан неверно.


 
brother ©   (2008-09-04 10:39) [52]

ты напиши как надо...


 
Юрий Зотов ©   (2008-09-04 11:00) [53]

> Игорь Шевченко ©   (04.09.08 10:26) [45]

> фичи ради фич

Не так. Во-первых, это фича ради обучения. Новичок, решивший эту задачу навсегда усвоит, что такое передача параметров по ссылке и по значению.

Во-вторых, этот метод внешнего управления выходом из внутреннего цикла процедуры я как-то вполне реально использовал во вполне реальной программе (точнее, библиотеке).


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

Юрий Зотов ©   (04.09.08 11:00) [53]

Я имею в виду предложенные пути реализации


 
Ega23 ©   (2008-09-04 11:02) [55]


> Во-вторых, этот метод внешнего управления выходом из внутреннего
> цикла процедуры я как-то вполне реально использовал во вполне
> реальной программе (точнее, библиотеке).


Вот в этом смысле - весьма интересное решение. Действительно можно брать на заметку...  :)


 
brother ©   (2008-09-04 11:04) [56]

такое использовал, и не раз, работало)


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


> Во-вторых, этот метод внешнего управления выходом из внутреннего
> цикла процедуры я как-то вполне реально использовал во вполне
> реальной программе (точнее, библиотеке).


Бить надо за такие вещи, где для выхода из внутреннего цикла используется внешнее управление (в смысле нет опроса внутри цикла)


 
Юрий Зотов ©   (2008-09-04 11:11) [58]

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

С этим согласен, за исключением [10]. Правда, и в [10] есть погрешность - что будет если нажать Button1 несколько раз подряд?
:о)

Заводя эту ветку, я все же рассчитывал на корректное поведение вполне взрослых людей (святая простота!) и предполагал, что пацаны сначала немного помучаются, а потом мы опубликуем решение [10] и поговорим с ними о способах передачи параметров и описателях var, const, in, out, а заодно и о том, что такое соглашения о вызове и как их использовать.

Увы, не получилось. Я забыл, где нахожусь и не учел особенностей контингента...


 
oxffff ©   (2008-09-04 11:28) [59]


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


> Юрий Зотов ©   (04.09.08 11:11) [58]


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

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


 
{RASkov} ©   (2008-09-04 11:32) [60]

> [59] oxffff ©   (04.09.08 11:28)
> Поэтому задача была намеренно усложнена.

Вот дать тебе штангу в полтонны и заставить поднять.... Сразу супермэном станешь, ага? :)


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


> Однобокость (шаблонность) мышления часто бывает неотъемлеммой
> чертой профессионала.
> Однако гибкость мышления(из знание нескольких несвязанных
> вариантов решения) эта черта характеризует суперпрофессионала.
>


Это, интересно, характерная черта данного форума или конкретных индивидуумов - огрызаться в ответ ?


 
oxffff ©   (2008-09-04 11:36) [62]


> {RASkov} ©   (04.09.08 11:32) [60]


Я жал от груди 120 на 3. Сейчас не занимаюсь.
Я поступлю проще. Я распилю на 4 или 5 частей. И подниму частями.
Ведь задача решена не так ли?


 
antonn ©   (2008-09-04 11:37) [63]


> пацаны сначала немного помучаются

местные "пацаны" в уме решат, а другие, с куда меньшими знаниями, тут не задерживаются. стараниями все тех же "пацанов".


 
Юрий Зотов ©   (2008-09-04 11:44) [64]

> oxffff ©   (04.09.08 11:28) [59]

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

LOL.

Однако, даже и суперпрофессионалам тоже не помешало бы перестать мыслить однобоко и шаблонно. Да и просто хотя бы начать мыслить. Чтобы понять некоторые вещи, к программированию напрямую не относящиеся.


 
oxffff ©   (2008-09-04 11:47) [65]


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


Почему вы настройчиво воспринимаете это именно так? :)
Будьте гибче, мы же учимся у друг друга.
Ключевая фраза друг у друга.

>Бить надо за такие вещи, где для выхода из внутреннего цикла >используется внешнее управление (в смысле нет опроса внутри цикла)

Однако почему в вашей фразе столько категоричности?

Однако, а что если есть код, исправить который нельзя, но нужно что-то придумать. Вы я так понимаю, скажите нас этому не учили? :)


 
oxffff ©   (2008-09-04 11:54) [66]


> Юрий Зотов ©   (04.09.08 11:44) [64]
> > oxffff ©   (04.09.08 11:28) [59]
>
> Большое человеческое спасибо. Без Вас, суперпрофессонала,
>  я так бы никогда и не узнал, что я - однобоко и шаблонно
> мыслящий профессионал, даже не подозревающий, что существуют
> и неакадемические способы решения задач. А также и о том,
>  что это форум, где каждый чему-то учится у другого.


Улыбнуло. Честно.

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

Вопрос как вы решите задачу [12], если она встанет перед вами?
Покажите еще одно решение.


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

oxffff ©   (04.09.08 11:47) [65]

Я не против учиться хорошему. Но такому, чтобы это хорошее не приходило в противоречие с уже усвоенным хорошим.


> Однако почему в вашей фразе столько категоричности?
>
> Однако, а что если есть код, исправить который нельзя, но
> нужно что-то придумать. Вы я так понимаю, скажите нас этому
> не учили? :)


Ну вот оттуда и категоричность, что "исправить нельзя". Значит, бить надо того, кто написал код, который "исправить нельзя".
Я слишком много за свою программистскую деятельность наблюдал последствий того, что "надо что-то придумать". Последствия, в основном, удручающие. Бывают, безусловно, и редкие исключения, но они только подтверждают правило - программа должна быть ясной и понятной.


 
alley ©   (2008-09-04 12:01) [68]


> Rouse_ ©   (04.09.08 10:17) [42]

Написано ж - код процедуры менять нельзя, а ты меняешь, хоть и в рантайме :)


 
oxffff ©   (2008-09-04 12:06) [69]


> Ну вот оттуда и категоричность, что "исправить нельзя".
> Значит, бить надо того, кто написал код, который "исправить
> нельзя".
> Я слишком много за свою программистскую деятельность наблюдал
> последствий того, что "надо что-то придумать". Последствия,
>  в основном, удручающие. Бывают, безусловно, и редкие исключения,
>  но они только подтверждают правило - программа должна быть
> ясной и понятной.


Мы все сталкиваемся с этим ежедневно.
Ну нельзя заставить человека соблюдать все правила.
Ну не может человек смотреть на 15 шагов вперед.
А пользоваться его творением нужно. А эти решения представлены.


 
Игорь Шевченко ©   (2008-09-04 12:19) [70]


> Ну не может человек смотреть на 15 шагов вперед.
> А пользоваться его творением нужно. А эти решения представлены.
>


Тогда проще убить человека, раз он не может смотреть на 15 шагов вперед


 
Юрий Зотов ©   (2008-09-04 12:22) [71]

> oxffff ©   (04.09.08 11:54) [66]

Еще раз большое человеческое спасибо. Без Вас я так никогда и не узнал бы, что человека нужно учить думать по-разному и понимать отличие одного от другого. А всю оставшуюся жизнь категорично говорил бы, что нужно делать именно так.

Правда, я этого и не говорил (перечитайте ветку, о, внимательнейший!), но раз Вы, суперпрофессионал, так заявляете, то нам, сирым, не остается ничего другого, как только склонить главу перед почтенным гуру.

Однако, даже и суперпрофессионалам не мешало бы понимать некоторые элементарные вещи. В частности, что для того, чтобы человек смог думать по-разному, он должен знать значительно больше, чем новичок. И что для этого его сначала надо обучить хотя бы основам.

И ветка эта, как следует даже из ее названия, была заведена именно для НОВИЧКОВ, а не для упражнений по решению значительно более сложных задач. Поэтому полагаю, что пост [12] в ЭТОЙ ветке просто неуместен. Что Вам мешало завести СВОЮ ветку, а не оффтопить?

> как вы решите задачу [12], если она встанет перед вами?

Что задача (а, значит, и ее решение) нестандартны - это и козе понятно. Подобные задачи, как правило, решаются не вообще, а с учетом каких-то условий (например, что текст процедуры действительно в будущем не изменится (или изменится), что не будет (или будет) использован другой компилятор, другая ОС, другая аппаратная платформа и т.п.). Поэтому - когда такая задача встанет, тогда и буду решать, с учетом этих самых условий. Подобное было далеко не раз - и пока справлялся.

И на этом говорить о [12] я больше не буду, поскольку оффтоп. А к Вам есть конкретный вопрос: сколько конкретных людей Вы лично научили программировать? Назовите число.


 
Rouse_ ©   (2008-09-04 12:26) [72]


> Написано ж - код процедуры менять нельзя, а ты меняешь,
> хоть и в рантайме :)

Так я ж не на Зотыча задачу решение приводил, а на
> oxffff ©   (03.09.08 23:35) [12]


 
Игорь Шевченко ©   (2008-09-04 12:27) [73]

"Кривое не может сделаться прямым" Еккл. 1. 15


 
DiamondShark ©   (2008-09-04 14:07) [74]


> oxffff ©   (03.09.08 23:35) [12]
>
> я предлагаю усложнить задачу.
> До
>
> procedure Proc;
> begin
> ShowMessage("Процедура Proc стартовала");
> while True do
> begin
>   Sleep(1); // Это чтобы не грузить процессор
>   Application.ProcessMessages;
> end;
> ShowMessage("Процедура Proc завершилась");
> end;
>
> на одной кнопке запуск
> на второй корретный выход.
>
> P.S. Идеи кое какие на этот счет имеются, но до конца пока
> не довел.

Тоже мне бином Ньютона.

буттон1клик

Proc();

буттон2клик

Abort();


 
DiamondShark ©   (2008-09-04 14:11) [75]


> oxffff ©   (04.09.08 10:01) [41]

Гонишь. Здесь один единственный поток.


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


> DiamondShark ©   (04.09.08 14:07) [74]
> Тоже мне бином Ньютона.
> буттон1клик
> Proc();
> буттон2клик
> Abort();


Гонишь по полной. Садись ДВА.

P.S. Осторожней с выражениями.


 
oxffff ©   (2008-09-04 14:18) [77]


> DiamondShark ©   (04.09.08 14:11) [75]


Опять гонишь.
Представь ситуацию, что после Assign операции.
Произошло переключение потоков. А далее он стал выполняться на другом процессоре.


 
oxffff ©   (2008-09-04 14:27) [78]


> А к Вам есть конкретный вопрос: сколько конкретных людей
> Вы лично научили программировать? Назовите число.


Как я или вы можете сказать, что научили программировать?
Во первых это(научил) исключительно не объективное понятие.
А судьи кто?
Во вторых научить программировать нельзя.
Можно научить кодировать в рамках конкретного языка.
Плюс привить определенные знания в области алгоритмов.
Все остальное человек делает самостоятельно.
И самое главное программист учится всю жизнь.

Если вы переформулируете вопрос сколько человек прошло через меня в рамках курсов по программированию. то я могу вам точно сказать.

4 группы школьников.
2 группы студентов III курса.
одна группа специалистов предприятий в рамках
плюс порядка 10 подчиненных, которым я старался повысить профессиональные знания.


 
Slym ©   (2008-09-04 14:33) [79]

Ответ на [12]
не меняя кода этой процедуры мы можем менять код вызываемых процедур :)
делаем сплайсинг слипа

type TSleepProc=procedure(milliseconds: Cardinal);stdcall;
procedure MySleep;
asm
 pop EAX
 add EAX, 14
 pop EDX
 push eax
end;

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

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

procedure TForm1.Button2Click(Sender: TObject);
begin
 Intercept(Sleep,MySleep);
end;


 
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.77 MB
Время: 0.008 c
2-1221620684
Татьяна
2008-09-17 07:04
2008.10.26
Отчеты в Word


2-1221812490
Alex86
2008-09-19 12:21
2008.10.26
Вложенный запрос


2-1221664079
Dr. Genius
2008-09-17 19:07
2008.10.26
Гарантированное выключение ПК


2-1221641606
vegarulez
2008-09-17 12:53
2008.10.26
Вопрос про DBGrid.DataSource.DataSet.FieldValues[];


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





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский