Легкие нити в Акке

Недавно я прочитал о Quasar, который предоставляет "облегченные" / Go-подобные потоки "пользовательского режима" для JVM. (у него также есть система актеров, вдохновленная Erlang, такая как Akka, но это не главный вопрос)

Например:

package jmodern;

import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.strands.Strand;
import co.paralleluniverse.strands.channels.Channel;
import co.paralleluniverse.strands.channels.Channels;

public class Main {
    public static void main(String[] args) throws Exception {
        final Channel<Integer> ch = Channels.newChannel(0);

        new Fiber<Void>(() -> {
            for (int i = 0; i < 10; i++) {
                Strand.sleep(100);
                ch.send(i);
            }
            ch.close();
        }).start();

        new Fiber<Void>(() -> {
            Integer x;
            while((x = ch.receive()) != null)
                System.out.println("--> " + x);
        }).start().join(); // join waits for this fiber to finish
    }
}

Насколько я понимаю, приведенный выше код не порождает никаких потоков JVM/Kernel, все делается в потоках пользовательского режима (или так они утверждают), что должно быть дешевле (точно так же, как сопрограммы Go, если я правильно понял)

Мой вопрос заключается в следующем: насколько я понимаю, в Akka все по-прежнему основано на потоках JVM, которые в большинстве случаев сопоставляются с собственными потоками ядра ОС (например, pthreads в системах POSIX), например. насколько я понимаю, в Akka нет потоков пользовательского режима/go как co-routines/легковесных потоков, я правильно понял?

Если да, то знаете ли вы, является ли это дизайнерским выбором? или в будущем планируется создание легковесных потоков в Akka?

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

Я правильно понял более или менее? пожалуйста, поправьте меня, если я ошибаюсь.

*Я могу полностью спутать потоки пользовательского режима с go/co-routines и облегченными потоками, вопрос выше зависит от моего плохого понимания того, что все они являются одним и тем же.


person Eran Medan    schedule 01.05.2014    source источник
comment
Это то, что я помню из своего опыта работы с Python. И это не прямой ответ, но он может быть полезен. И пользовательские/облегченные потоки, и фактические системные потоки имеют свое применение. Это сводится к тому, что оба обеспечивают параллелизм, но только системные потоки обеспечивают параллелизм. Поэтому, если вы выполняете тяжелые вычисления, вы не получите никакого прироста от использования пользовательских потоков, но вы получите от системных потоков. В другой ситуации, когда у вас есть только одно ядро ​​ЦП и вам нужен сервер, использование пользовательских потоков является единственным решением.   -  person Anton    schedule 02.05.2014
comment
Да, это я тоже понимаю, т.е. пользовательские потоки хороши только для обеспечения хорошего использования ЦП, например. переключение между двумя пользовательскими потоками, которые иногда блокируют ввод-вывод, дешевле, чем использование полномасштабного потока. у вас нет параллелизма, но вы лучше используете ЦП, если я правильно понял   -  person Eran Medan    schedule 02.05.2014
comment
Пожалуйста, посмотрите мой ответ, он может быть полезен: stackoverflow.com/questions/29680718/   -  person circlespainter    schedule 20.04.2015


Ответы (2)


Akka — очень гибкая библиотека, и она позволяет вам планировать акторов, используя (по сути, это сводится к этому через цепочку трейтов) простой трейт ExecutionContext, который, как видите, принимает Runnable и каким-то образом их выполняет. Итак, насколько я понимаю, вполне вероятно, что можно написать привязку к чему-то вроде Quasar и использовать его в качестве «бэкенда» для актеров Akka.

Однако Quasar и подобные библиотеки, вероятно, предоставляют специальные утилиты для связи между волокнами. Я также не знаю, как они будут обрабатывать блокирующие задачи, такие как ввод-вывод, возможно, у них тоже есть механизм для этого. Я не уверен, что из-за этого Akka сможет правильно работать с зелеными потоками. Quasar также, кажется, полагается на инструментарий байт-кода, и это довольно продвинутая техника, которая может иметь много последствий, не позволяющих ему поддерживать Akka.

Тем не менее, вам не следует беспокоиться о легкости потоков при использовании акторов Akka. На самом деле, Akka прекрасно умеет создавать миллионы акторов в одной системе (см. ">здесь), и все эти актеры будут работать нормально.

Это достигается за счет продуманного планирования специальных видов пулов потоков, таких как пул потоков fork-join. Это означает, что если субъекты не заблокированы в каком-либо длительном вычислении, они могут работать в количестве потоков, значительно меньшем, чем число этих субъектов. Например, вы можете создать пул потоков, который будет использовать не более 8 потоков (по одному на каждое ядро ​​8-ядерного процессора), и все действия акторов будут планироваться на этих потоках.

Гибкость Akka позволяет настроить конкретный диспетчер для использования конкретными акторами, если это необходимо. Вы можете создать специальные диспетчеры для субъектов, которые остаются в длительных задачах, таких как доступ к базе данных. См. здесь для получения дополнительной информации.

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

person Vladimir Matveev    schedule 01.05.2014
comment
Меньше потоков — меньше переключений контекста при той же задержке. Короче говоря, да, вы можете рассмотреть возможность использования пользовательских потоков, если можете. - person Ivan Balashov; 27.06.2016
comment
Это достигается за счет продуманного планирования для специальных видов пулов потоков ‹- Где я могу получить больше информации о том, как это на самом деле делается (в самой простой форме)? - person Franz; 04.02.2017
comment
@Franz Я не уверен в самой простой форме, но вы можете начать с чтения о диспетчерах в документации akka, а затем перейдите непосредственно к документации для пул потоков с разветвлением. Вы также можете погуглить о пулах потоков fork-join, вы найдете много руководств и объяснений. - person Vladimir Matveev; 06.02.2017

Актеры Akka по сути являются асинхронными, и поэтому их может быть много, в то время как акторы Quasar (да, Quasar также предлагает реализацию акторов), которые очень близки к Erlang, являются синхронными< /em> или блокировка, но они используют файберы, а не потоки Java (т.е. в текущей ОС), так что вы все равно можете иметь их много с той же производительностью, что и асинхронный, но стиль программирования такой же простой, как при использовании обычных потоков и блокировке вызовов.

Ввод-вывод осуществляется посредством интеграции: Quasar включает платформу для преобразования как асинхронного, так и синхронного API. в блокировку оптоволокна и Comsat уже включают множество таких интеграций (одна с Java NIO включена непосредственно в Квазаре).

Мой ответ на другой вопрос содержит дополнительная информация.

person circlespainter    schedule 25.10.2015