Подтвердить что ты не робот

С# для продолжения первого класса с помощью взаимодействия С++ или каким-либо другим способом?

У нас очень высокая производительность многозадачности, около С# приложения реального времени. Эта работа была достигнута в первую очередь за счет внедрения совместной многозадачности на дому с помощью планируемого на дому планировщика. Это часто называют микропотоками. В этой системе все задачи взаимодействуют с другими задачами через очереди.

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

В частности, проблема возникает в двух случаях, связанных с очередями. Всякий раз, когда какая-либо конкретная задача выполняет какую-либо работу перед размещением элемента в очереди. Что делать, если очередь заполнена?

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

Мы решили это в 90% случаев, связывая очереди с задачами, чтобы избежать вызова задач, если какая-либо из их исходящих очередей заполнена, или входящая очередь пуста.

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

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

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

Был пример где-то из пользовательского хоста CLR, чтобы потоки .NET фактически работали как "волокна", которые по существу позволяют переключать состояние стека между потоками. Но теперь я не могу найти какой-либо образец кода для этого. Плюс, кажется, что это займет некоторую значительную сложность, чтобы исправить это.

Есть ли у кого-нибудь другие креативные идеи, как эффективно переключаться между задачами и избегать вышеуказанных проблем?

Есть ли другие хосты CLR, которые предлагают это, коммерческое или иное? Есть ли какая-либо добавочная библиотека, которая может предложить некоторую форму продолжения для С#?

4b9b3361

Ответ 1

Собственно, мы решили руководствоваться этим. Мы используем шаблон Observer с Message Passing. Мы построили домашнюю библиотеку для обработки всех сообщений между "Агентами", которые похожи на процесс Erlang. Позже мы рассмотрим возможность использования AppDomains для еще лучшего разделения агентов друг от друга. Идеи дизайна были заимствованы из языка программирования Erlang, который имеет чрезвычайно надежную многоядерную и распределенную обработку.

Ответ 2

Существует С# 5 CTP, который выполняет преобразование в стиле продолжения с использованием методов, объявленных с помощью нового ключевого слова async, и при вызове ключевого слова await.

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

Ответ 3

Нет, не собираюсь работать. С# (и даже IL) является слишком сложным языком для выполнения таких преобразований (CPS) в общем виде. Лучшее, что вы можете получить, это то, что предложит С# 5. Тем не менее, вы, вероятно, не сможете сломать/возобновить цикл с более высокими циклами/итерациями, которые действительно хотят, чтобы вы захотели от общедоступных повторных продолжений.

Ответ 4

Режим волокна был удален из v2 CLR из-за проблем со стрессом, см.:

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

Поддержка волоконных волокон FYI была предназначена для существующих приложений, использующих волокна (например, SQL Server) для размещения CLR таким образом, чтобы они могли максимизировать производительность, не как метод для разрешить приложения .Net для создания переходов потоков - в коротких волокнах - это не волшебное решение вашей проблемы, однако если у вас есть приложение, которое использует волокна для размещения CLR, тогда управляемые API-интерфейсы хостинга действительно предоставляют средства, чтобы CLR "хорошо работала" с вашим приложением. Хорошим источником информации по этому вопросу будет документация по управляемому хостинговому API или посмотреть, как SQL Server поддерживает CLR, из которых несколько высокоинформативные статьи.

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

Ответ 5

Решение вашей проблемы заключается в использовании алгоритмов без блокировки, обеспечивающих системный прогресс по крайней мере в одной задаче. Вам необходимо использовать встроенный ассемблер, который зависит от ЦП, чтобы убедиться, что вы атомизированный CAS (сравнение и обмен). В Wikipedia есть статья а также шаблоны, описанные в книге Дуглас Шмидт назвал "Структурно-ориентированная архитектура программного обеспечения, шаблоны для параллельных и сетевых объектов" . Мне не сразу понятно, как вы это сделаете в рамках инфраструктуры dotnet.

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

Надеюсь, это было полезно?