Что такое потоки в Ruby и почему они полезны?

Изучая JavaScript, вы, возможно, слышали (неоднократно), что JavaScript - это однопоточный язык с асинхронной обработкой. Именно эта асинхронная обработка позволяет использовать AJAX и современный Интернет. Но что означает «однопоточный»? А как бы выглядел «многопоточный» язык?

Однопоточный

Строго говоря, однопоточный язык - это язык, в котором команды обрабатываются по порядку, по одной за раз. Если это правда, как может JS - однопоточный язык - работать асинхронно? Короткий ответ заключается в том, что асинхронная обработка происходит где-то еще: в цикле событий. Ответ средней длины - это великий разговор Филиппа Робертса о том, что такое цикл событий и как он работает.

Многопоточность

Ruby, с другой стороны, поддерживает многопоточность как неотъемлемую часть языка. Это позволяет уменьшить использование памяти и ускорить выполнение кода. Обратной стороной является то, что все это управление потоками зависит от вас: вы должны запускать и повторно присоединяться к потокам в своей программе самостоятельно, а также следить за тем, чтобы они были упорядочены и управлялись должным образом. Технически многопоточность в Ruby является параллельной, но не параллельной. Это означает, что он не может использовать преимущества нескольких ядер и запускать код одновременно, технически он все еще прыгает от потока к потоку для выполнения кода. Вы можете решить эту проблему с помощью чего-то вроде JRuby, потому что многопоточность в Java может использовать преимущества нескольких ядер и запускать код параллельно.

Как мне создать новую тему?

Ruby делает это довольно просто:

a = Thread.new{sleep 1; puts "I'm Thread A"}
b = Thread.new{puts "I'm Thread B"}
a.join
b.join

Это производит:

> I'm Thread B
> I'm Thread A

Сравнить с:

def a
  sleep 1
  puts "I'm Method A"
end
def b
  puts "I'm Method B"
end
a
b

который производит (через 1 секунду):

> I'm Method A
> I'm Method B

Метод join позволяет нам вернуться к ранее объявленным потокам. Кроме того, с этими потоками можно работать как с объектами, поэтому мы можем создавать их и возвращаться к ним программно. Если у нас есть два отдельных источника информации, к которым можно получить доступ независимо, это может ускорить нашу программу, чтобы получить доступ к ним с помощью отдельных потоков, предоставляя нам функции, аналогичные запросам на выборку и обещаниям в JavaScript. И, как и в JS, это хороший вариант, если вы выполняете одновременные HTTP-запросы. Это более сложный способ написания программ, но если вы работаете над более сложными операциями с данными, многопоточность - отличный способ повысить эффективность вашего кода.

Потоки мощные! Но сложно осмыслить

Я настоятельно рекомендую почитать Threads, если вам интересно - есть несколько отличных примеров и пошаговых руководств на RubyLearning.com, и, конечно же, вы можете найти полные объяснения многочисленных методов и вариантов использования потоков в Ruby Docs. .