Sobes.tech
Middle+

Czym jest Fiber w Ruby?

sobes.tech AI

Odpowiedź od AI

Fiber w Ruby to lekkie wątki wykonania (koreogramy), które pozwalają na tworzenie wielu równoległych wątków wykonania w ramach jednego procesu/wątku systemu operacyjnego. Umożliwia to zarządzanie kolejnością wykonywania kodu, przełączając się między Fiberami bez angażowania planisty systemu operacyjnego.

Główne cechy Fiber:

  • Kooperacyjne planowanie: Fiber nie są wywłaszczane przez jądro systemu operacyjnego. Przełączanie między nimi odbywa się jawnie za pomocą metod resume i yield.
  • Pojedynczy wątek: Wszystkie Fiber w jednym wątku wykonują się kolejno, ale przełączanie między nimi tworzy iluzję równoległości dla kodu wewnątrz wątku.
  • Zachowanie stanu: Fiber zapamiętuje swój stan (zmienne lokalne, punkt wykonania) podczas wywołania yield i wznawia go podczas wywołania resume.

Zastosowania Fiber:

  • Implementacja kodu asynchronicznego: Modelowanie operacji nieblokujących bez użycia callbacków lub złożonych konstrukcji.
  • Iteratory i generatory: Tworzenie złożonych iteratorów, które generują wartości na żądanie.
  • Obsługa automatów skończonych: Modelowanie stanów i przejść w sposób jawny.

Przykład użycia:

# Tworzenie Fiber
fiber = Fiber.new do
  puts "Cześć z Fiber 1"
  value1 = Fiber.yield(1) # Wstrzymanie wykonania, zwraca 1
  puts "Odebrano z Fiber 1: #{value1}"

  puts "Cześć z Fiber 2"
  value2 = Fiber.yield(2) # Wstrzymanie wykonania, zwraca 2
  puts "Odebrano z Fiber 2: #{value2}"

  puts "Cześć z Fiber 3"
  3 # Zakończenie Fiber, zwraca 3
end

puts "Main: Przed pierwszym resume"
result1 = fiber.resume # Wznawia wykonanie Fiber
puts "Main: Odebrane z Fiber: #{result1}"

puts "Main: Przed drugim resume"
result2 = fiber.resume("z Main 1") # Wznawia i przekazuje wartość
puts "Main: Odebrane z Fiber: #{result2}"

puts "Main: Przed trzecim resume"
result3 = fiber.resume("z Main 2") # Wznawia i przekazuje wartość
puts "Main: Odebrane z Fiber: #{result3}"

Metody główne:

  • Fiber.new { ... }: Tworzy nowy Fiber. Blok kodu jest wykonywany przy pierwszym wywołaniu resume.
  • fiber.resume(*args): Wznawia wykonanie Fiber. Argumenty przekazane do resume stają się wartością zwracaną przez Fiber.yield lub argumentami bloku startowego.
  • Fiber.yield(*args): Wstrzymuje bieżący Fiber i zwraca kontrolę do kodu, który go uruchomił (resume). Argumenty przekazane do yield stają się wartością zwracaną przez resume.
  • Fiber.current: Zwraca bieżący Fiber.

Różnice między Fiber a Thread:

Cecha Fiber Thread
Planowanie Kooperatywne (jawne przełączanie) Preemptive (zarządzane przez system)
Zasoby Lekki (mniej zasobów) Cięższy (więcej zasobów)
Równoległość Fałszywa równoległość w ramach jednego wątku Prawdziwa równoległość (używa rdzeni CPU)
Komunikacja Przez yield i resume Przez wspólną pamięć, przekazy wiadomości itp.
Debugowanie Relatywnie prostsze (liniowy przepływ) Bardziej skomplikowane (wyścigi, blokady)

Fiber zapewniają niższopoziomowy mechanizm kontroli wykonania w porównaniu do Thread, wymagając jawnego zarządzania przełączeniami.