производитель-потребитель, используя назначение - PullRequest
3 голосов
/ 05 августа 2009

Я заинтересован в том, чтобы выяснить, можно ли решить проблему «производитель-потребитель» при наличии нескольких продуктов и нескольких потребителей без использования назначения, т. Е. С использованием функционального стиля программирования? Как?

Проблема производителя-потребителя

Спасибо

Ответы [ 5 ]

3 голосов
/ 06 августа 2009

Да. Проверьте функциональное реактивное программирование (FRP), которое связано с Concurrent ML (предложение Нормана), но является чисто функциональным. Семантика FRP весьма «параллельна», но имеет простую, точную, детерминистическую, функциональную семантическую модель (функции времени).

Редактировать: Я процитировал здесь "параллельный", потому что я не имею в виду обычное операционное (ориентированное на реализацию) понятие параллелизма, которое является императивным и недетерминированным, поэтому воспрепятствование практическому и надежно правильному мышлению.

3 голосов
/ 05 августа 2009

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

3 голосов
/ 05 августа 2009

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

Хотя можно оценивать несколько частей функции параллельно, как в операторе `` par на Haskell, это не то же самое, что проблема производитель-потребитель, и поэтому я не рассматриваю это Не думаю, что вы сможете решить ее функционально.

1 голос
/ 05 августа 2009

Есть много способов решить эту проблему; у каждого свои недостатки.

Например, «пут» может порождать новый поток каждый раз. Таким образом, вам вообще не понадобится буфер. Если поступает много запросов, вы создаете много потоков, пока ваш ЦП не будет больше занят переключением между потоками, чем их выполнением. Но это просто перемещает проблему из вашего кода в ОС: в определенный момент вам всегда нужно синхронизировать доступ к переменной в памяти. ОС должна поддерживать список потоков, и доступ к этому списку должен быть синхронизирован.

Либо вы хотите ограничить количество потоков (тогда «пут» должен иметь возможность читать переменную, в то время как потоки могут завершаться одновременно и уменьшать ее -> снова синхронизированный доступ). Или вы рискуете исчерпать ресурсы, потому что у вас слишком много потоков.

Вы можете отправить сообщение, когда вызывается «put», и потребители могут прослушать сообщение. Но это только сложный способ реализовать «ожидание» потоков. И вам нужен способ убедиться, что только один потребитель получит сообщение. Опять же, вам понадобится некоторая синхронизированная структура данных.

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

1 голос
/ 05 августа 2009

Все реализации, которые я видел от производителя-потребителя в SML, были вынуждены полагаться на ref s (для поддержания очереди «спящих» элементов), поэтому я бы сказал «нет ».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...