Потоки Ruby на самом деле проще, чем вы думаете. Все, что вам действительно нужно сделать, это инкапсулировать фрагмент кода, который вы хотите обрабатывать одновременно, используя:

Thread.new{}

Вызывая эту функцию несколько раз, мы можем заставить программу обрабатывать несколько потоков одновременно. Идеально, и мы все сделали правильно.

2.times do |i|
    Thread.new {
        10000000.times do |t|
        t + 1
        end
        ending = Time.now
        elapsed = ending - starting
        puts ("#{i} End:" + elapsed.to_s)
     }
end
ending = Time.now
elapsed = ending - starting
puts ("Main End:" + elapsed.to_s)

Теперь, если мы попытаемся поместить этот код в ruby ​​и запустить все, время выполнения будет отличным. Но подождите, куда делся код, ставит (#{i} End: + elapsed.to_s)? Мы не можем найти никаких упоминаний о времени, прошедшем для каждого запуска. Это связано с тем, что при работе с потоками в Ruby нам нужно снова соединить поток с основной программой, чтобы любая из ее информации присутствовала. Если основная программа завершится раньше потока, то поток автоматически завершится вместе с основной программой.

Для этого мы можем установить поток равным значению, а затем снова присоединить его к основной программе.

x = Thread.new{}
x.join

Это хорошо, но что происходит, когда мы хотим работать с несколькими потоками. Должны ли мы каждый раз создавать новую тему и присоединяться к ней? Ну, знай, что есть способы обойти это. Например, добавление наших потоков в массив, а затем их объединение в конце.

Теперь, когда мы можем работать с несколькими потоками, давайте проверим это.

Это простой пример многопоточности, который позволит нам синхронизировать наши программы. Убедитесь, что в верхней части вашего файла требуется «контрольный показатель», чтобы синхронизировать вашу программу двумя разными способами.

Все, что нам нужно сделать, это удалить часть кода «threads ‹‹ Thread.new{}» и перезапустить все, чтобы проверить это без потоковой обработки.

Странно, когда мы смотрим на времена рядом, они выглядят почти одинаково.

Проблема в том, что мешает встроенный в CRuby механизм Global Interpreter Lock.

Глобальная блокировка интерпретатора (GIL) — это механизм, используемый в интерпретаторах компьютерного языка для синхронизации выполнения потоков, чтобы мог выполняться только один собственный поток. за раз (Википедия). Это заставляет Ruby работать только с одним потоком за раз, переключаясь между ними для выполнения заданных задач.

Хотя это не означает, что в Ruby нет смысла использовать многопоточность, у него все еще есть несколько реализаций. Одним из наиболее распространенных применений является использование потоков для настройки фоновой информации для нашей программы путем объединения потоков в конце программы. Сделав это, наша основная программа закончит свою работу и непосредственно перед завершением соединит все вместе.

Останавливаться здесь кажется неуместным, должен же быть способ ускорить обработку нашей программы? Да, используя JRuby, мы сможем запустить приведенный выше код и ускорить процесс. JRuby создан для запуска потоков с параллелизмом, а не параллелизмом, как CRuby.

В стандартном Ruby есть еще один способ «потока» — использование метода fork() вместо метода Thread.new{}.

Делая это, вы можете заставить нашу программу работать так, как будто она запускает несколько приложений одновременно. Наш компьютер может обрабатывать только несколько вещей, работающих одновременно, поэтому, если вы увеличите все слишком сильно, наш терминал сломается.