Любая точка элемента, меняющая свои внутренние поля, не может вызываться из параллельных потоков.
Как и не может "кольцеваться"
Ну не будет такое корректно работать:
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