Библиотека для потока данных в C - PullRequest
1 голос
/ 18 июня 2010

Как я могу сделать поток данных (каналы и фильтры, обработка потока, на основе потока) в C? И не с трубами UNIX.

Я недавно сталкивался с stream.py .

Потоки являются итеративными с конвейерным механизмом, позволяющим программировать потоки данных и легко распараллеливать.

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

Я хотел бы продублировать простую версию этого вида функциональности в C. Мне особенно нравится перегрузка оператора >>, чтобы избежать путаницы при составлении функций. Википедия указывает на этот намек от поста Usenet в 1990 году.

Почему С? Потому что я хотел бы иметь возможность делать это на микроконтроллерах и в расширениях C для других языков высокого уровня (Max, Pd *, Python).

* (ирония, учитывая, что Макс и Pd были написаны на С, специально для этой цели - я ищу что-то скелетов)

Ответы [ 3 ]

2 голосов
/ 19 июня 2010

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

Я написал прототип DF-сервера (вместе с моим другом), который имеет несколько нереализованныхфункций пока нет: он может только передавать данные Integer и Trigger в сообщениях, и он не поддерживает паралеллизм.Я только что пропустил эту работу: порты производителя компонентов имеют список указателей функций на потребительские порты, которые устанавливаются при инициализации и вызывают его (если список не пустой).Таким образом, при возникновении события компоненты выполняют древовидную структуру графа потока данных.Поскольку они работают с целыми числами и триггерами, это чрезвычайно быстро.

Кроме того, я написал странный компонент, который имеет один потребительский порт и один порт производителя, он просто передает данные через - но в другом потоке.Это потребительская процедура быстро заканчивается, так как она просто помещает данные и устанавливает флаг для потока на стороне производителя.Грязный, но он удовлетворяет моим потребностям: он отсоединяет длинные процессы обхода дерева.

Итак, как вы могли заметить, это асинхронная система с низким трафиком для быстрых задач, где размер графика не имеет значения.

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

Я думаю, самое большоеПроблема в DF-сервере является диспетчером.Параллелизм, коллизия, потоки, приоритет ... как я уже сказал, я только что пропустил проблему, а не решил.Вы должны пропустить это тоже.И вам также следует пропустить другие проблемы.

Диспетчер

В случае синхронной архитектуры DF все компоненты должны запускаться один раз за цикл, кроме особых случаев.У них есть простое предварительное условие: доступны ли входные данные?Таким образом, вам нужно просто просканировать компоненты и передать их в поток бесплатных звонков, если данные доступны.После обработки всех них у вас будет N оставшихся компонентов, которые еще не были обработаны.Вы должны обработать список снова.После второй обработки у вас останется М остатков.Если N == M, цикл закончен.

Я думаю, что какой-то такой же материал сработает, если число компонентов меньше 100.

Связывание

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

 // disclaimer: not actual code
 Component* c1 = new AddComponent();
 Component* c2 = new PrintComponent();
 c2->format = "The result is %d\n";
 bind(c1->result,c2->feed);

Легко написать, хорошо читается, другое желание?

Сообщение

Вы должны передавать чистые необработанные пакеты между портами компонентов.Вам нужен только список привязок, который содержит пары указателей портов производителя и потребителя и содержит обработанный флаг, который использует «диспетчер».

Вызов проблемы

Проблема в том, что производитель должен вызывать не потребительский порт, а компонент;все переменные компонента (класса) и выстрелы находятся в компоненте.Таким образом, производитель должен напрямую вызывать общую точку входа компонента, передавая ему идентификатор потребителя, или он должен вызывать порт, который должен вызывать любой метод компонента, которому он принадлежит.


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

Если у вас есть дополнительные вопросы, не стесняйтесь их задавать, я часто просматриваю здесь ключевое слово «поток данных».

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

1 голос
/ 20 июля 2010

Это круто: http://code.google.com/p/libconcurrency/

Облегченная библиотека параллелизма для C, с симметричными сопрограммами в качестве основной абстракции потока управления.Библиотека похожа на State Threads, но использует сопрограммы вместо зеленых потоков.Это упрощает межпроцедурные вызовы и в значительной степени устраняет необходимость использования мьютексов и семафоров для передачи сигналов.

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

Эта библиотека была вдохновлена ​​«минимальным пакетом потоков пользовательского уровня» Дугласа В. Джонса.Псевдоплатформенный алгоритм зондирования на соединительной линии svn получен из его кода.

Существует также более безопасная и более переносимая реализация сопрограммы, основанная на копировании стека, которая была вдохновлена ​​страницей sigfpe о переносимых продолжениях в CКопирование является более переносимым и гибким, чем стековое переключение, и изучается вопрос о том, как сделать копирование конкурентоспособным по сравнению с переключением.

1 голос
/ 18 июня 2010

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

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

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

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

...