Фиберы в VB

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

Модератор: BV

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Фиберы в VB

Сообщение tyomitch » 24.09.2004 (Пт) 20:37

типа, претендую на статью... надо же когда-то начинать...

Использование фиберов в VB для одновременного выполнения нескольких задач.
В Win98+/WinNT35+ доступны фиберы, т.е. выполняемые задачи, управление которыми не осуществляется системой, а возложено на программиста. Говорят, они были введены в WinNT для облегчения переноса UNIX-приложений, где существовало несколько видов нитей, как управляемые системой, так и управляемые программистом.
В соответствии с "текстильной" аналогией, процесс состоит из нитей, а нити - из фиберов. У каждого фибера, как и у нити, сохраняется контекст, т.е. внутреннее состояние - значения регистров и т.п. Однако фиберы выполняются строго попеременно, из-за чего отпадает необходимость в запутанной синхронизации задач, которая так усложняет разработку многонитёвых приложений. Переключения между фиберами осуществляются не по инициативе системы, а по запросу программиста. Фиберы сродни "сопрограммам" в книге Кнута "Искусство программирования", т.е. процедурам с несколькими точками входа и несколькими точками выхода.
Поскольку многофиберные приложения могут быть и однонитёвые, они вполне реализуемы в VB. Однако, к моему удивлению ни одного примера такого приложения я в Интернете не нашёл. Придётся восполнить этот пробел.
Для примера рассмотрим одновременный поиск простых чисел и решений задачи Диофанта от Daz. Не самый жизненный пример, но уж какой есть :-)
Самое главное в этом примере - его, в принципе, можно было написать и на таймерах, - это удобство программирования. Вместо хранения счётчиков каждого цикла в статических переменных, мы пишем цикл именно так, как писали бы его без одновременно выполняемого другого.
Сложности с отладкой определённые есть, но я считаю их несущественными - например, нельзя делать Step Into (F8) на вызове SwitchToFiber, и нельзя нажимать End, когда выполняется не главный фибер. В общем же, код работает прекрасно и под отладчиком, и в скомпилированном виде.
В примере для пущей эффектности выводится только каждое сотое простое число - иначе их список быстро переполняется.
Ещё несколько примечаний касательно применения фиберов стоят прямо в коде примера.

ПРИЛОЖЕНИЕ: краткая историческая справка.
Идея заюзать фиберы в VB для имитации многонитёвости пришла мне в январе с.г. ( http://groups.google.com/groups?selm=42 ... put=gplain ) Довольно быстро я получил работающее многофиберное приложение (из десятка строк), но прогресс застопорился из-за неожиданной проблемы: я так и не смог придумать, где многофиберность может понадобиться ( http://groups.google.com/groups?selm=42 ... put=gplain ) Однако идея о том, что фиберы всё-таки могут быть полезны, дремала во мне до тех пор, пока Daz не предложил задачу Диофанта. Вот тогда-то мне и пришла в голову идея этого примера. Daz-у огромная благодарность :-)
Других примеров использования многофиберности в VB, кроме моего, гуглу неизвестно. Так что считаю себя первопроходцем :-)
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось tyomitch 24.09.2004 (Пт) 22:23, всего редактировалось 5 раз(а).
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 24.09.2004 (Пт) 20:40

Щас будем читать, щас...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 24.09.2004 (Пт) 20:49

Никак не могу допетрить, в каком месте изменяется pFiberNext. Он же всё время один и тот же :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 24.09.2004 (Пт) 21:57

GSerg писал(а):Никак не могу допетрить, в каком месте изменяется pFiberNext. Он же всё время один и тот же :)

Он свой в каждом фибере. Т.е. есть два разных pFiberNext, каждый из них - не меняется.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 24.09.2004 (Пт) 22:14

Не понял...
Ни фига не понял.
Ни фи га.

Начинается процедура Main. Она переключается на pFiberPrimes, передавая ...


Ёпрст :)
НУ тут же как в таймере приснопятном многопоточном :) lParam при создании, конечно же :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 24.09.2004 (Пт) 22:20

Быстро писать исчерпывающую статью и отсылать её Гайдару, ознакомившись с правилами :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 24.09.2004 (Пт) 22:41

Следующий шаг в развитии технологии: объектно-ориентированные фиберы, без ObjPtr и CopyMemory!

Вот теперь уже можно заворачивать всё в .zip и писать Гайдару.

[edit]Вот, ещё менеджер фиберов написал для максимального удобства их использования. Почему-то ExitFiber работает только в скомпилированном файле - всю голову сломал, но так и не понял, почему. Какие у кого идеи?[/edit]
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось tyomitch 25.09.2004 (Сб) 13:32, всего редактировалось 1 раз.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 24.09.2004 (Пт) 23:00

Гы :)
Во как :)
Ничё, мы всё равно... Мы и это будем юзать, и от мультитрединга не откажемся :)

[edit]Ну вот, опять копать... Ща посмотрим...[/edit]
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.09.2004 (Сб) 14:40

Имхо, дело в GetCurrentFiber. Попробуй поиграться с адресом fs:[]. Может дело в том же самом, что и при переадресации вызова под IDE (см. выводы Approximator’а)? Там смещение в IDE не 4 байта от стека, а 8. Может, и тут что-то такое?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 25.09.2004 (Сб) 15:46

GSerg писал(а):Имхо, дело в GetCurrentFiber. Попробуй поиграться с адресом fs:[]. Может дело в том же самом, что и при переадресации вызова под IDE (см. выводы Approximator’а)? Там смещение в IDE не 4 байта от стека, а 8. Может, и тут что-то такое?

Нет, дело точно не в этом - я проверяю в фибере GetCurrentFiber, и он именно такой, какой должен быть.
Тут имхо дело опять в "квантовых эффектах": если я ставлю брякпойнт, то IDE останавливается не на нём, а в FiberManager::Yield с текущим фибером, равным pFiberMy. После этого всё, как и описано в MSDN, рушится.
Крайне странно, что бряк происходит именно тогда, когда должен был бы произойти. Просто совсем в другом месте, и я не понимаю, как вообще выполение может зайти в FiberManager::Yield в контексте главного фибера.
Что-то тут действительно такое впечатление, что IDE нарочно все карты путает. Но как такое может быть? Переход без jmp-а - новое слово в программировании :-)

А если брякпойнт не ставить, то всё просто рушится, и никак не понять где :-(
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 25.09.2004 (Сб) 16:32

А ты в файл пиши после выполнения каждой команды. Найдёшь, по идее.

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

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 25.09.2004 (Сб) 23:23

GSerg писал(а):А ты в файл пиши после выполнения каждой команды. Найдёшь, по идее.

Ага, вроде нашёл... Нет, всё-таки тяжело с IDE сосуществовать. Если убрать вызов DeleteFiber, всё работает; если оставить, то падает на первом же COM-вызове после неё. Такое впечатление, что DeleteFiber конкретно херит какие-то IDE-шные thread-local структуры. Но не TLS, раз скомпилированное всё работает. В чём же дело? что такое есть у нити в IDE, чего нету в скомпилированном файле?
Может, вообще выкинуть нафиг эту DeleteFiber? Пусть разшедуленные фиберы лежат себе в памяти...

И ещё, где почитать, что лежит в fs:[] ? Там, судя по всему, куча интересных вещей лежит :-)

GSerg писал(а):Но вообще, это куда более недокументированная методика, как я посмотрю :)

это - это что? В файл писать?
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 26.09.2004 (Вс) 23:55

Кажется, я понял, в чём дело: IDE хранит собственный "стек" вызываемых процедур где-то в fs:[], возможно, это как-то связано с SEH. При вызове ExitFiber процедура удаляемого фибера ещё остаётся в этом "стеке", потому что из неё не было выхода. DeleteFiber освобождает эту память, и IDE при попытке чтения своего "стека" рушится.
Поэтому если поставить DeleteFiber вне цикла, то всё работает гладко - к этому времени процедура удалённого фибера уже удаляется из "стека" (кстати, интересно почему), и поэтому же происходят интересные вещи на брякпойнте - фиберы "конфликтуют" с данными VB о том, какая сейчас процедура выполняется.
А дело всё в том, что к концепции сопрограмм неприменимы понятия вызывающей и вызываемой процедуры, и поэтому "стек вызовов" там не имеет смысла. Но IDE всё равно пытается построить стек вызовов и падает именно поэтому.
Всё это не более чем домыслы на основании наблюдаемых фактов. Возможно, всё совсем по-другому; тогда я вообще не знаю, в чём дело.
Approximator и другие любители глубокого бурения, плз помогите! Такая модная технология, и совсем ещё нераспаханная!
Изображение


Вернуться в Наши проекты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 35

    TopList