Вверх ↑
Этот топик читают: Гость
Администрация
Ответов: 15295
Рейтинг: 1519
#16: 2006-10-05 16:37:38 ЛС | профиль | цитата
Если про компонент написано, что точки ## расцениваются как зарезервированные, то правильно было бы выполнить это требование. Не зависимо от того, понадобятся они когда нибудь или нет.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#17: 2006-10-05 17:03:21 ЛС | профиль | цитата
Ситуация очень простая:
Если есть примеры (с подключением обработчика события), в которых некий Self работает, а некий EventHandle - нет (при параллельной работе экземпляров мультика), то контр аргументация этого топика имеет под собой объективное содержание.

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

0
Администрация
Ответов: 15295
Рейтинг: 1519
#18: 2006-10-05 17:34:19 ЛС | профиль | цитата
А всетаки что уже сейчас будет не верно работать при использование Thread в MultiElementEx?
карма: 27
0
Ответов: 9906
Рейтинг: 351
#19: 2006-10-05 19:06:22 ЛС | профиль | цитата
Ну я не знаю уже как объяснять...

Любая точка элемента, меняющая свои внутренние поля, не может вызываться из параллельных потоков.
Как и не может "кольцеваться"
Ну не будет такое корректно работать:
Add(Thread,3187940,161,112)
{
link(onExec,3721202:doWork1,[(228,118)])
}
Add(Thread,11817348,161,182)
{
link(onExec,3721202:doWork3,[(228,188)])
}
Add(For,11361622,259,147)
{
}
Add(HubEx,3721202,224,140)
{
link(onEvent,11361622:doFor,[])
}


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

И логически анализируя, делаю выводы, что рекурсия в ООП - это: а) создать объект б) вызвать метод объекта с) уничтожить при необходимости. ((Что успешно делает режим OnlyOnce.))
Сколько не пытался объяснить - не помогает: вместо возможности линка на верхний уровень, мы совершенствуем технологию "кольцевания"
То же самое про параллельные потоки - синхронизация потоков переложена на программиста.
И такая схема уже будет работать без проблем
Add(Thread,3187940,161,105)
{
link(onSyncExec,3721202:doWork1,[(228,118)])
}
Add(Thread,11817348,161,175)
{
link(onSyncExec,3721202:doWork3,[(228,188)])
}
Add(For,11361622,259,147)
{
}
Add(HubEx,3721202,224,140)
{
link(onEvent,11361622:doFor,[])
}
И это совершенно эквивалентно потоку внутри мультика - выходы всех экземпляров схемы подключены к одной выходной точке. И если выходные события не синхронизированы - конфликт данных неизбежен.

Вот это работать не будет: code_379
А, если синхронизировать потоки - будет: code_380
карма: 9

0
файлы: 2code_379.txt [1KB] [550], code_380.txt [1.1KB] [582]
Администрация
Ответов: 15295
Рейтинг: 1519
#20: 2006-10-05 19:29:38 ЛС | профиль | цитата
Так я же конкретно про MultiElementEx спрашивал. Выходит, что сам по себе он на данный момент не содержит ошибок как при однопоточной так и многопоточной схеме.

А вот такая схема:
Add(Thread,3187940,161,105)
{
link(onSyncExec,3721202:doWork1,[(228,118)])
}
Add(Thread,11817348,161,175)
{
link(onSyncExec,3721202:doWork3,[(228,188)])
}
Add(For,11361622,259,147)
{
}
Add(HubEx,3721202,224,140)
{
link(onEvent,11361622:doFor,[])
}
к сожалению не обязяна работать без проблем, как это не печально. Вставляем в любое звено после цикла вызов метода doProcessMessage и получаем туже самую картину.



вообще соблязняет идея сделать некоторый подтип точек ##MT_XXX, которые для событий и данных возвращали бы в поток Self текущей схемы вместе с данными через точку, а для методов и св-тв наоборот принимали бы Self из потока(так же вместе с данными) и миную всякие ##Select сразу же вызывали бы точки нужного экземпляра схемы. При таком подходе работа могла бы выглядеть так:
Add(MultiElementEx,10015731,280,189)
{
link(onEvent,627223:doGet,[])
}
BEGIN_SDK
Add(EditMultiEx,15553146,3,3)
{
WorkCount=#6:doWork|
EventCount=#7:onEvent|
}
END_SDK
Add(MT_Get,627223,336,189)
{
link(onData,944798:doValue,[])
link(onGet,14880513:Method,[(385,202)(385,254)])
}
Add(Memory,944798,392,189)
{
}
Add(MT_Add,5086822,224,189)
{
link(onAdd,10015731:doWork,[])
link(Data,944798:Value,[(230,179)(320,179)(320,231)(398,231)])
}
Add(PointHint,14880513,427,231)
{
Info=#55:Получаем событие из схемы с некоторыми данными в потоке|
VAlign=0
Width=141
Height=46
link(Event,12465804:Method,[(584,254)(584,319)(22,319)(22,250)])
}
Add(PointHint,12465804,35,227)
{
Info=#67:Выполняем все, что требуется и пересылаем данные в нужную нам схему|
VAlign=0
Width=155
Height=46
link(Event,5086822:doAdd,[(207,250)(207,195)])
}
Add(InfoTip,15323863,189,287)
{
Info=#21:Делаем все, что хотим|
Transparent=1
VAlign=1
Width=239
Height=67
}
Add(InfoTip,8085811,378,119)
{
Info=#29:Сохраняем Self активной схемы|
Height=109
}
Add(InfoTip,8273264,210,126)
{
Info=#26:Подшиваем сохраненный Self|
Height=109
}
карма: 27
0
Ответов: 9906
Рейтинг: 351
#21: 2006-10-06 22:06:12 ЛС | профиль | цитата
1) Содержит или не содержит ошибки конкретно MultiElementEx, зависит от понимания, что есть ошибка. И проблема, как раз, в неодинаковости этого понимания.
Для ЛЮБОГО элемента

2) Это не проблема схемы - а проблема элемента ProcessMessage. Который является инструментом рекурсивного вызова. Того самого, без генерации новых экземпляров объектов.
Фактически - это то же самое "не визуализированное кольцевание"
И может уронить не только эту схему.
Модальные формы еще таким качеством обладают.

3) Меня не привлекает. И не будет привлекать до тех пор, пока MT-техника не приобретет достаточную степень надежности.
Там сегодня есть проблемы. Поэтому, сегодня возводить надстройки, без укрепления фундамента - не стал бы.


Плохим фактором является безусловное изменение структуры входных/выходных данных, по сравнении с инлайнингом мультика.
Если не безусловное, а опциональное, тогда необходимо:

1) Индекс/хэндл схемы должен добавляться не в "хвост", а в "голову". Которые снимаются в MultiElementEx, еще до EditMulti

2) Должны быть специальные типы данных (MultiHandle, MultiIndex) для них - по ним и определяется необходимость индексирования/отсечения данных. Обеспечивая возможность стандартного режима работы.

3) Можно принимать индекс/хендл с верхней точки с зарезервированным именем. С приоритетом, аналогичным стандартному

4) И принимать хэндл события удобней с нижней точки, чем с MT (который может там конечно, и быть, но опять - в "голове", а не в "хвосте" ).
Потому что элемент Memory ничуть не корректнее к параллельным потокам, чем поле MultiElementEx.EvHandle - а схемной мороки побольше будет.

5) Self вещь нужная, независимо от темы этого топика. Но, устроен он должен быть совсем по-другому. Это должен быть объект похожий на элемент, но с уникальными св-ми. Он должен воплощать в себе беспроблемность вызова методом класса ЛЮБОГО метода данного класса. Т.е., он должен иметь комплект скрытых точек, полностью совпадающий со списками EditMultiEx. Ну, возможно, несколько специальных....


[size=-2]------ Добавлено в 22:06
А вот подать на ##Add данные для внешних св-в в виде MT-списка - было бы дело ..........
И реализовать это CodeGen-ом в конструкторе схемы...

В одном загвоздка - СРЕДА не сообщает в CodeGen о том, какое св-во внешнее, а какое нет
Надо бы придумать такой интерфейсный метод с префиксом sdk ...
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#22: 2006-10-07 14:30:38 ЛС | профиль | цитата
5) не понятно только как его лучше всего сделать.
карма: 27
0
Ответов: 2125
Рейтинг: 159
#23: 2006-10-08 16:39:06 ЛС | профиль | цитата
Вот, кстати, по поводу Self и SelfIndex, я сделал у себя в CodeGen в процедуре codePoint такие изменения: code_399
Для CI_MultiElement не было особой необходимости делать проверку типа точки, но я думаю - так более логично.
Соответственно добавил в hiEditMultiEx
procedure THIEditMultiEx.SelfIndex;
begin
dtInteger(Data, THIMultiElementEx(FParent).FindChild(Self));
end;
Ну ещё FindChild надо было public-ом сделать...
карма: 1

0
файлы: 1code_399.txt [882B] [434]
Ответов: 9906
Рейтинг: 351
#24: 2006-10-08 17:02:59 ЛС | профиль | цитата
Да не вопрос, что едиобразие лучше, чем отсутствие такового.
Вот только мне представляется, что более единообразным был бы второй парсинг MultiElementEx, а не EditMulti.
Внешние данные подходящие снаружи более понятны, ИМХО
Чем данные, принимаемые с "потолка"

Ну и наконец, посмотрим на получившееся:
  1. Я имею несколько событий, к которым (всем ) приаттачиваю в "голову" (как-то ) Self. На выходах снимаю этот Self-ы в элементы Memory для использования - не проблема, скажем.
  2. В своем варианте, просто использую точку EventHandle (для всех событий ) - с нулевым расходом элементной базы (Ex-ы не считаются)
  3. И чего проще
карма: 9

0
Ответов: 2125
Рейтинг: 159
#25: 2006-10-08 17:08:06 ЛС | профиль | цитата
И чего проще ?
А делать EventHandle так, чтобы он для каждого Thread-a выбирался свой - проще? Не, ну можно конечно завести список EventHandle (на каждый Thread), в принципе - не такая уж и проблема.
карма: 1

0
Ответов: 9906
Рейтинг: 351
#26: 2006-10-08 17:42:01 ЛС | профиль | цитата
А не надо этого делать.
И не надо не синхронизированными Thread-ами запускать один и тот же элемент, имеющий внутренние поля.
Memory к примеру. Или есть варианты использования Self-техники без этого

Не надо - это если хочешь чтобы оно (независимо от моих доработок) работало.
И откуда такая уверенность, что Self "сверху" позволит это делать.
НЕ ПОЗВОЛИТ.

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

[size=-2]------ Добавлено в 17:19
tsdima писал(а):
Не, ну можно конечно завести список EventHandle (на каждый Thread), в принципе - не такая уж и проблема

Но не нужно.
Потому что это не решит ни одного вопроса много поточности.


[size=-2]------ Добавлено в 17:42


Ну для наведения полной ясности, можно поступить так: я выкладываю много поточную задачечку и реализую ее по своему.
И, чтобы работало - буду вынужден синхронизировать потоки
А ты ПОПРОБУЕШЬ рассказать, как это же самое сделать в Self-технике без синхронизации

А
карма: 9

0
Ответов: 2125
Рейтинг: 159
#27: 2006-10-08 21:33:27 ЛС | профиль | цитата
я выкладываю много поточную задачечку
Многопоточные задачи - это отдельная песня. Я же просто, так как уже сталкивался с необходимостью запоминать свой собственный индекс внутри мультика в Memory, хочу упростить этот процесс. Вот и всё. Зачем хранить в дополнительной переменной то, что уже может быть доступно.

Вот кстати, по поводу:
procedure THIEditMultiEx.onEvent;
var X:THIEditMultiEx;
begin
X := THIMultiElementEx(FParent).EvHandle;
THIMultiElementEx(FParent).EvHandle := self;
_hi_onEvent(THIMultiElementEx(FParent).Events[Index],Data);
THIMultiElementEx(FParent).EvHandle := X;
end;
Что будет, если в процессе обработки _hi_onEvent тот мультик, что был сохранён в Х, будет уничтожен? Правильно - Runtime error ...
карма: 1

0
Ответов: 9906
Рейтинг: 351
#28: 2006-10-08 22:49:26 ЛС | профиль | цитата
tsdima писал(а):
Зачем хранить в дополнительной переменной то, что уже может быть доступно
Да для того, чтобы убрать кучу элементов из схемы. Но ты почему-то не высказываешься про три вышеупомянутые пункта.
Храню, потому что он мне нужен снаружи, а не изнутри. И чтобы иметь для этого нулевой расход элементной базы. И имею. Затратами в три команды проца. Очень быстрых команды.

Я ведь тоже сталкивался, и тоже хочу упростить


tsdima писал(а):
Что будет, если в процессе обработки _hi_onEvent тот мультик, что был сохранён в Х, будет уничтожен? Правильно - Runtime error ...
Правильно - именно Runtime error ...
А без этого, что, блин, не было Когда событие уничтожает своего прародителя.
Вот писал же выше:
btw: я иного способа уничтожить самого себя, иначе как через таймер (PostMessage - по большому счету) и не придумал пока

карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#29: 2006-10-09 02:36:09 ЛС | профиль | цитата
Что будет, если в процессе обработки _hi_onEvent тот мультик, что был сохранён в Х, будет уничтожен? Правильно - Runtime error ...


Когда событие уничтожает своего прародителя.

насколько я понял задачу, то тут ни о каком уничтожение самого себя речи не идет. В X мы сохраняем указатель на вообще говоря любую схему внутри контейнера. А значит, к примеру, _hi_onEvent, который удалит все схемы кроме себя самого и вызовет Runtime error. а значит после
THIMultiElementEx(FParent).EvHandle := X;[/code]
X надо проверять на валидность.

[quote]Затратами в три команды проца[/quote]
Self и SelfIndex это 0 команд проца для тех, кому эта ф-ность не нужна и в помине...
карма: 27
0
Ответов: 9906
Рейтинг: 351
#30: 2006-10-09 11:04:44 ЛС | профиль | цитата
Dilma писал(а):
Self и SelfIndex это 0 команд проца для тех, кому эта ф-ность не нужна и в помине
Это - да.
А сколько затрат для тех кому нужна
Ну не виноват я, что Self нужен "снаружи". А "внутри" нужны, скорее, его поля....
Абстрактный, но конкретный пример: code_405
А теперь зададимся вопросом: сколько элементов добавится в Self-технике
А теперь пусть таких выходных событий штуки 4 (у меня сегодня так, скажем)...

Dilma писал(а):
А значит, к примеру, _hi_onEvent, который удалит все схемы кроме себя самого и вызовет Runtime error
Только не следует забывать, что этот самый _hi_onEvent (который удалит все схемы кроме себя самого) был тоже кем-то вызван. А именно: схемой, которую он удалил.
И Run Time Error будет независимо от использования EvHandle.
Следовательно, проверка X на валидность - бессмысленной становится.
Осмыссленным остается вопрос, как в Delete определить "занятость" схемы. И это опять не очень зависит от evHandle-фичи.... Но вопрос конечно же
карма: 9

0
файлы: 1code_405.txt [1.5KB] [411]
Сообщение
...
Прикрепленные файлы
(файлы не залиты)