HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby
   
 
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 11.02.2025, 17:25
Receiver
Постоянный
Регистрация: 26.03.2016
Сообщений: 660
С нами: 5332594

Репутация: 163


По умолчанию

Привет! Поговорим сегодня о волокнах (fibers) в Windows. Да что вы знаете о волокнах? Кто-нибудь вообще о них слышал? Оказывается слышал. Поэтому начнём обо всём по порядку.

Что из себя представляет волокно?Вырезка из 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
)
;


И зачем в итоге это всё нужно?С помощью этой дичи мы можем очень легко склепать самопальный менеджер короутин позволяющий вручную управлять выполнением программы и при этом не бояться гонки данных, но только при однопоточной работе приложения! Я уже занимался подобным 22-м году, так что можете ознакомиться: https://www.blast.hk/threads/118982/. Только скажу что на практике это бесполезно, потому что никакого выигрыша по времени не даёт, к тому же сам Microsoft говорит что волокна может лишь упростить перенос приложений. Поэтому всем заинтересованным в короутинах порекомендовал бы использовать asio.
 
Ответить с цитированием
 





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.