Можно ли использовать реализацию core.async в ClojureScript в Clojure?

Можно ли использовать реализацию core.async на основе конечного автомата ClojureScript в Clojure, а не реализацию Clojure на основе потоков? Я хотел бы иметь возможность использовать core.async на JVM, но без использования потоков.


person exupero    schedule 12.02.2014    source источник
comment
(go) также реализовано с использованием конечного автомата в clj. см. документ для (go) и источник github.com/clojure/core.async/blob/   -  person edbond    schedule 12.02.2014
comment
Естественно, но я имею в виду использование в ClojureScript конечных автоматов вместо потоков, а не отсутствие конечных автоматов в реализации Clojure.   -  person exupero    schedule 12.02.2014
comment
Мне любопытно - почему вы хотите избежать использования потоков?   -  person Shepmaster    schedule 12.02.2014
comment
Я хотел бы использовать core.async на RoboVM для разработки iOS, но фоновые потоки не могут работать с пользовательским интерфейсом.   -  person exupero    schedule 12.02.2014
comment
Вы можете вернуться к основному потоку, чтобы работать с пользовательским интерфейсом, например. эта функция: core.async/take!   -  person Daniel Ziltener    schedule 24.06.2014


Ответы (2)


В настоящее время это невозможно, но ничто не мешает вам изменить core.async для поддержки однопоточной модели. Вся диспетчеризация обрабатывается через clojure.core.async.impl.dispatch/run Измените эту функцию, чтобы использовать какой-то другой метод диспетчеризации, и все должно работать. Версия core.async для ClojureScript имеет другую версию dispatch/run, которая использует setTimeout (или другие вещи, которые могут быть быстрее). Скопируйте этот код и измените его, чтобы он работал на вашей виртуальной машине, и это не должно быть таким трудным изменением.

person Timothy Baldridge    schedule 12.02.2014

Невозможно использовать core.async на JVM строго в однопоточном режиме, если только вы не хотите заглянуть внутрь и заменить пул потоков, используемый для go, на тот, который использует только один поток.

Однако, как указывает Эдбонд в своем комментарии, версия core.async для Clojure использует конечные автоматы для обработки gos. Затем эти конечные автоматы запускаются в потоках из пула потоков, размер которого ограничен удвоенным числом процессоров + 42, поэтому можно запускать тысячи go без использования большого количества реальных потоков.

Core.async JVM также предоставляет макрос thread, который работает как go, но запускает настоящие потоки, а также набор операций двойного взрыва (<!!, >!! и т. д.), которые работают так же, как их аналоги одиночного взрыва, но блокирующим образом. Используете ли вы их, зависит от вас; если вы придерживаетесь go и семейства однократных операций, core.async никогда не будет запускать потоки за пределами вышеупомянутого предела пула потоков.

person Michał Marczyk    schedule 12.02.2014
comment
Сначала я подумал, что 42 это милая шутка для целей ответа, но потом я проверил clojure/core/async/impl/exec/threadpool.clj#L21" rel="nofollow noreferrer">код и увидел, что это действительно милая шутка. :-) - person Shepmaster; 12.02.2014