Привет! Поговорим сегодня о волокнах (fibers) в Windows. Да что вы знаете о волокнах? Кто-нибудь вообще о них слышал? Оказывается слышал. Поэтому начнём обо всём по порядку.
После нам нужно будет создать второе волокно. Создавать волокна мы можем только из волокон, поэтому мы конвертировали поток.
Теперь уже можно заниматься их переключением и делается это очень просто:
Помимо прочего мы можем получить адрес текущего волокна:
Это может пригодиться наверное лишь для проверок, чтобы не допустить рекурсии.
Волокнам точно так же как и потокам нужно хранить принадлежащие им статические данные. Поэтому для этого используется абсолютно идентичный потокам механизм, за исключением изменения одной буквы в аббревиатуре — FLS (Fiber Local Storage). Текущий FLS переключается как при изменении самого волокна, так и управляющего им потока. Управлять этой структурой можно с помощью следующих функций:
Что из себя представляет волокно?
Вырезка из MSDN:Если говорить на языке фактов, то волокно это управляемый поток. Механизмом работы волокна не отличается от потока. Они не выигрывают по производительности, но зато дают одно важное преимущество пользователю — возможность управления. При этом сами волокна подчиняются потокам, ведь по время их работы Windows продолжает планировать потоки. При переключении с потока выполняющего Fiber на другой его выполнение так же будет приостановлено и продолжиться лишь при обратном переключении.Волокно — это единица выполнения, которую приложение должно запланировать вручную. Волокна выполняются в контексте потоков, которые планируют их. Каждый поток может запланировать несколько волокон. Как правило, волокна не предоставляют преимуществ по сравнению с хорошо спроектированными многопоточных приложений. Однако использование волокон может упростить перенос приложений, предназначенных для планирования собственных потоков.
Как работать с волокном?
Первое что мы должны сделать так это конвертировать поток в волокно:
C++:
// Конвертирует текущий поток в волокно
// Возвращает очень важное значение LPVOID - адрес созданного волокна
// Его нужно хранить для последующих переключений
LPVOID ConvertThreadToFiber(
[in, optional] LPVOID lpParameter
);
// Этой функцией можно получить данные переданные
// волокну в lpParameter, если такие есть
PVOID GetFiberData();
C++:
// Создаёт новое волокно из уже существующего
// Так же возвращает адрес волокна требующий сохранения
LPVOID CreateFiber(
[in] SIZE_T dwStackSize, // рамзер стека (можно ставить 0)
[in] LPFIBER_START_ROUTINE lpStartAddress, // вызываемая функция
[in, optional] LPVOID lpParameter
);
// lpParameter точно так же можно получить внутри волокна через GetFiberData
C++:
// Переключает текущее волокно
void SwitchToFiber(
[in] LPVOID lpFiber // адрес волокна на которое нужно переключиться
);
C++:
// Возвращает адрес текущего волокна
PVOID GetCurrentFiber();
Как волокна хранят данные?
Волокнам точно так же как и потокам нужно хранить принадлежащие им статические данные. Поэтому для этого используется абсолютно идентичный потокам механизм, за исключением изменения одной буквы в аббревиатуре — FLS (Fiber Local Storage). Текущий FLS переключается как при изменении самого волокна, так и управляющего им потока. Управлять этой структурой можно с помощью следующих функций:
C++:
// Если указан FLS Callback, то вызывается при: удалении волокна, выходе потока, удалении FLS
PFLS_CALLBACK_FUNCTION PflsCallbackFunction;
void PflsCallbackFunction(
[in] PVOID lpFlsData
)
// Создаёт FLS возвращаего его индекс.
DWORD FlsAlloc(
[in] PFLS_CALLBACK_FUNCTION lpCallback
);
// Возвращает значение по индексу FLS
PVOID FlsGetValue(
[in] DWORD dwFlsIndex
);
// Устанавливает значение по индексу FLS
BOOL FlsSetValue(
[in] DWORD dwFlsIndex,
[in, optional] PVOID lpFlsData
);
// Удаляет FLS
BOOL FlsFree(
[in] DWORD dwFlsIndex
);