Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

22.03.2024

Клас Fiber в Ruby - кооперативна рівночасність

🧶 Готую тут матеріал про засоби рівночасності в Ruby, та відкрив для себе клас Fiber. Він дуже схожий на Thread, але насправді корисний зовсім в інших умовах. (Якщо ці назви класів перекладати, то все стає ще заплутаніше, тому я не буду.)

Fiber, на відміну від Thread, не є рівночасними в типовому розумінні. Натомість виконання передається від Fiber до Fiber явно, командами resume / yield. До виклику такої команди буде виконуватись тільки поточний Fiber - навіть у разі очікування на IO. Тобто можна сказати, що Fiber гарантовано не будуть паралельними.

Навіщо таке взагалі потрібно? Явно не для пришвидшення програми — його ми тут не побачимо. А для спрощення алгоритмів звернемо увагу, що кожний Fiber має власний стек. Це відкриває чудові можливості кооперації рекурсивних процесів.

Наприклад: нескладно написати обхід дерева. Але що якщо потрібно обійти одночасно два дерева? (Може, ми хочемо знайти між ними різницю.) Тут вже традиційна рекурсія не влаштовує. Я в такій ситуації зазвичай перетворюю рекурсію на цикл з “емуляцією” стеку — тобто положення в дереві відстежую у власній структурі даних.

Звісно, такий код буде складніше, ніж просто рекурсія. Тому я відразу побачив перевагу Fiber - з ними можна запустити дві рекурсії паралельно та взагалі не перейматись про внутрішню форму алгоритму. Це чудовий підхід для роз’єднання деталей виконання, які зазвичай тісно поєднані. Більше — в майбутній статті.