Преимущества зеленых нитей по сравнению с простой петлей

Есть ли какое-либо преимущество в использовании green threads / lightweight threads по сравнению с простым циклом или последовательным кодом, если в обоих случаях используются только неблокирующие операции?

for i := 0; i < 5; i++ {
    go doSomethingExpensive() // using golang example
}

// versus

for i := 0; i < 5; i++ {
    doSomethingExpensive()
}

Насколько я могу судить
- зеленые потоки помогают избежать ада обратных вызовов при асинхронных операциях
- позволяют планировать M зеленых потоков на N потоках ядра

Но
- добавляется немного сложности и производительности, требующей планировщика
- упрощается взаимодействие между потоками, когда язык поддерживает это, а выполнение было разделено на разные процессоры (в противном случае последовательный код проще)


person Alex    schedule 08.02.2016    source источник
comment
По крайней мере, в Go или Erlang облегченные процессы будут использовать несколько ядер, поэтому они будут иметь те же преимущества, что и потоки ОС. В других реализациях легковесных процессов (я думаю, в Python greenlets?) вы этого не сделаете, и особой разницы нет.   -  person twotwotwo    schedule 16.02.2016


Ответы (1)


Нет, зеленые потоки не дают никаких преимуществ в производительности вообще.

Если потоки выполняют неблокирующие операции:

  • Несколько потоков не имеют преимуществ, если у вас есть только одно физическое ядро ​​(поскольку одно и то же ядро ​​должно выполнять все, потоки только замедляют работу из-за накладных расходов).

  • До количества потоков, равного количеству ядер ЦП, вы получаете преимущество в производительности, поскольку несколько ядер могут выполнять ваши потоки физически параллельно (см. Платформу Play!).

  • Зеленые потоки не имеют никаких преимуществ, так как они выполняются из одного и того же реального потока подпланировщиком, поэтому на самом деле зеленые потоки == 1 поток

Если потоки выполняют блокирующие операции, все может выглядеть иначе:

  • несколько потоков имеет смысл, так как один поток может быть заблокирован, но другие могут продолжаться, поэтому блокировка замедляет только один поток.
  • вы можете избежать ада обратного вызова, просто реализовав свой частично блокирующий процесс как один поток. Поскольку вы можете блокировать один поток, например. ожидая IO, вы получаете гораздо более простой код.

Зеленые нити

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

Зеленые потоки широко использовались в ранние дни Java, когда JVM не поддерживала настоящие потоки ОС. Вариант зеленых потоков, называемый волокнами, является частью операционной системы Windows и, например. сервер MS SQL активно использует их для обработки различных сценариев блокировки без значительных накладных расходов, связанных с использованием реальных потоков.

Вы можете выбирать не только среди зеленых и реальных тем, но также можете рассматривать продолжения (https://www.playframework.com/documentation/1.3.x/asynchronous)

Продолжения дают вам лучшее из обоих миров:

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

Этот подход достаточно ресурсоемкий. Играть в! framework использует столько потоков, сколько ядер процессора у вас есть (4-8), но превосходит все высокопроизводительные серверы приложений Java с точки зрения производительности.

person Gee Bee    schedule 16.02.2016