Кто-нибудь работал с сабжем на VB?
В МСДH пишут, что это дешёвый и лёгкий способ добиться одновременного
выполнения нескольких задач, который не требует явной синхронизации и не
конфликтует с нереентрабельным нутром VB. Однако ни одного примера работы с
ними на VB я так и не видел. Они есть?
--
Сергей Мерзликин
http://www.smsoft.ru/ru/
s...@smsoft.ru
SM> Думаю, что в VB5/6 это работать не будет. В силу того, что каждый
SM> Fiber работает в отдельном потоке, будут те же проблемы доступа к TLS,
SM> что и при многопоточности.
Наоборот, все фиберы работают в одной нити (дать ссылку на МСДН или на слово поверишь?), поэтому "должно бы" работать.
Факт же в том, что почему-то нет. Даже в VB5, где CreateThread падает не сразу, SwitchToFiber вешает машину намертво (МЕ), или же
только падает (2000). Что-то я, наверное, делаю не так, но что? Вот код:
=========Beginning of the citation==============
Option Explicit
Public Declare Function CreateFiber Lib "kernel32.dll" (ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lParam As
Long) As Long
Public Declare Sub DeleteFiber Lib "kernel32.dll" (lpFiber As Any)
Public Declare Function ConvertThreadToFiber Lib "kernel32.dll" (ByVal lParam As Long) As Long
Public Declare Sub SwitchToFiber Lib "kernel32.dll" (lpFiber As Any)
Dim pMainFiber As Long
Sub Main()
Dim pNewFiber As Long
pMainFiber = ConvertThreadToFiber(0)
pNewFiber = CreateFiber(0, AddressOf FiberProc, 1)
SwitchToFiber pNewFiber
DeleteFiber pNewFiber
End Sub
Sub FiberProc(ByVal lParam As Long)
SwitchToFiber pMainFiber
End Sub
=========The end of the citation================
SM> Да и преимуществ особых не вижу, поскольку переключать
SM> Fiber'ы нужно вручную, того же эффекта можно добиться при грамотном
SM> использовании DoEvents.
Вовсе нет. При использовании DoEvents "по простому" начнёт работать любое событие, которое захочет, вплоть до того же, которое
DoEvents вызвало. Приходится иметь по флагу для каждого события, который проверяется на входе в обработчик, и устанавливать нужные
флаги перед вызовом DoEvents. С SwitchToFiber же я могу явно указать, чему дать продолжить работать.
--
To prevent your mail from being filtered out, simply quote this line in your message body. A464E022
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
Видимо, я невнимательно прочитал. Там написано: "If your fiber function
returns, the thread running the fiber exits", из чего я заключил, что все
они в разных потоках. Сейчас проверил - это не так.
> Public Declare Sub DeleteFiber Lib "kernel32.dll" (lpFiber As Any)
Здесь надо ByVal использовать ^^^^^^^
И лучше As Long
> Public Declare Sub SwitchToFiber Lib "kernel32.dll" (lpFiber As Any)
И здесь тоже ^^^^^^^
Как минимум, в XP это работает. Кстати, в Windows 95 этих функций не
предусмотрено.
> SM> Да и преимуществ особых не вижу, поскольку переключать
> SM> Fiber'ы нужно вручную, того же эффекта можно добиться при грамотном
> SM> использовании DoEvents.
> Вовсе нет. При использовании DoEvents "по простому" начнёт работать любое
событие, которое захочет, вплоть до того же, которое
> DoEvents вызвало. Приходится иметь по флагу для каждого события, который
проверяется на входе в обработчик, и устанавливать нужные
> флаги перед вызовом DoEvents. С SwitchToFiber же я могу явно указать, чему
дать продолжить
работать.
Возможно. Но я бы в таком случае попробовал изменить архитектуру программы,
и написать центральный диспетчер заданий, из которого бы все вызывалось, и в
который бы все возвращалось, а длительные вычисления бы разбивал на короткие
части, и между ними заставлял бы алгоритм возвращаться в центральный
диспетчер. Как-то это событийно-ориентированнее будет.
SM> Возможно. Hо я бы в таком случае попробовал изменить архитектуру
SM> программы, и написать центральный диспетчер заданий, из которого бы все
вызывалось,
SM> и в который бы все возвращалось, а длительные вычисления бы разбивал на
SM> короткие части, и между ними заставлял бы алгоритм возвращаться в
центральный
SM> диспетчер. Как-то это событийно-ориентированнее будет.
Фиберы имеют то преимущество, что при переключении к фиберу он начинает
выполняться не с точки входа, а с того места, где выполнение
прервалось. Таких мест в нём может быть 10 и 20, и разбивать все промежутки
между ними на отдельные события может быть больно.
Хотя если честно, ни одной конкретной задачи, где фиберы бы помогли, я так и
не придумал. Буду думать ещё.
09 Jan 04 20:30:56 в RU.VISUAL.BASIC A. Skrobov -> Sergey Merzlikin:
AS> Фиберы имеют то преимущество, что при переключении к фиберу он начинает
AS> выполняться не с точки входа, а с того места, где выполнение
AS> прервалось. Таких мест в нём может быть 10 и 20, и разбивать все
AS> промежутки между ними на отдельные события может быть больно.
AS> Хотя если честно, ни одной конкретной задачи, где фиберы бы помогли, я так
AS> и не придумал. Буду думать ещё.
Если многопоточность очень нужна, то напиши этот участок программы на сях в
виде ATL-библиотечки с одним синхронизирующим COM-объектом. Это не так сложно.
Всего хорошего!
Дмитрий Козырев aka Master
AS>> Public Declare Sub DeleteFiber Lib "kernel32.dll" (lpFiber As Any)
SM> Здесь надо ByVal использовать ^^^^^^^
SM> И лучше As Long
AS>> Public Declare Sub SwitchToFiber Lib "kernel32.dll" (lpFiber As Any)
SM> И здесь тоже ^^^^^^^
SM> Как минимум, в XP это работает. Кстати, в Windows 95 этих функций не
SM> предусмотрено.
Вот из-за этих двух шняг и глючило. Спасибо.
Теперь осталось придумать, зачем это нужно :-)