LINUX.ORG.RU

IPC события в одном потоке

 ,


0

2

Смеркалось.

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

Мне не нравится что во всех случаях, кроме сигналов, чтение – забота принимающего сигнал: то есть мне надо либо сидеть в блокировке и ждать сообщения (это не то что мне нужно, мне нужно чтоб программа работала все время) либо заводить отдельный тред и сидеть в блокировке там, а когда придет сообщение – звать уже колбек (это будет план БЭ, хочу поспрашать нет ли чего проще/дешевле). А сигналы мне не нравятся потому что пользовательских всего два, а привязать к ним данные – это надо отдельную песню городить ( ну типа по сигналу, например, выгребать сообщение из очереди )

В общем, как эксперты по всему решают эту проблему? Мож есть какая общеизвестная либа или как обычно зоопарк? Нужно для сей на сабжевую ОС, само собой. Предалгайте!

★★★★★
Ответ на: комментарий от olelookoe

крч излагай, что ты там делаешь когда данные пришли.

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

Щас там есть бинарь, который в себе аггрегирует всякие разные настройки: настройки железяки, айпишники там, адреса сервера, пути – короче мешанина из наших переменных и системных – от производителя железяки. Каждый раз ее запустить – 2-3 секунды, пока оно там все проинициализирует, все что ей надо опросит – тяжелая в общем.

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

pihter ★★★★★
() автор топика

На одном хосте, обычно ещё есть shared memory. Вот это прям память память, когда хочешь - пиши, когда хочешь читай. Синхронизацию между процессами только будь добр реализовать если не готов жить с состоянием гонки.

В boost’e для крестов, есть полная обвязка, чтобы сделать например процессо-безопасную очередь.

faq2
()
Последнее исправление: faq2 (всего исправлений: 1)
Ответ на: комментарий от faq2

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

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

Спасибо кэп. Выше было описано как это сделать Ъ, но тред читать очевидно выше/ниже/не отвечает Вашего достоинства;-)

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от pihter

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

Останется понять как проще и дешевле всего пинать процессы что бы они че то оттуда забрали. Можно это делать даже сигналом. Но мне кажется это более Ъ чем 100500 файлов/сокетов/пайпов…

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

То есть воткнуть в основный цикл поднятие/опускание блокировки можно, а вызов функции которая переменные перенастраивает нельзя? Второе кажется гораздо более простым…

Оно там поголовно сделано на фреймверке: главный цикл там SERVER_START какой-то поко-макрос. Можно конечно впихнуть все что угодно, но пока у них тут – священная корова

pihter ★★★★★
() автор топика
Ответ на: комментарий от AntonI

в обычных линуксах то tmpfs это та же память.

у меня тоже

Останется понять как проще и дешевле всего пинать процессы что бы они че то оттуда забрали

Тред именно про это. Общие переменный на основе тмпфс у меня уже.

Можно это делать даже сигналом

Да как-то не думаю что это повысит надежность. Сигналы в линуксах – больно суровые

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

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

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

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

olelookoe ★★★
()
Ответ на: комментарий от pihter

Тред именно про это.

Мнэ… еще одна общая таблица на tmpfs в которой прописаны версии переменных? Версия поменялась - читай новую переменную.

Оно там поголовно сделано на фреймверке: главный цикл там SERVER_START какой-то поко-макрос. Можно конечно впихнуть все что угодно, но пока у них тут – священная корова

А асинхронность в этот фреймворк не завезли? Может там можно че то эдакое фигакнуть в параллель, но так что оно не приводит к гонке данных?

AntonI ★★★★★
()
Ответ на: комментарий от olelookoe

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

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

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

Это не спасет от неатомарности чтения/записи файла. Тем более, ниже ты пишешь, что читателей больше одного и они копошатся в поисках сообщений адресованых им. А раз копошатся, значит поди еще и в основном цикле или дополнительном треде?

deep-purple ★★★★★
()
Ответ на: комментарий от olelookoe

в этом случае очевидная шареная память

Она там есть, как один из десятка настройкоскладов. Дело не в обмене настройками, а именно – пнуть надо. Ну, например, сервер прислал команду, получающий процесс ее принял, обработал, расшифровал, в журнал записал – надо заинтересованным процессам ее передать. Именно событие. Как это через ШМ?

pihter ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Проверка валидности данных спасает. Если данные не валидны - они просто недописаны, придем в следующий раз.

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

Версия поменялась - читай новую переменную

Да твое предложение понятно. Проблема в том, что за этим надо следить чтоб получить момент события. Если следить – то и просто переменной достаточно, спору нет. Я же вопрошал как организовать передачу СОБЫТИЯ. То есть момента времени. Чтоб по этому пинку из вне в процессе начал выполнятся код обработки события.

А асинхронность в этот фреймворк не завезли?

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

Через ШМ гемор. Возьми пайпы — тут и атомарность и асинхронность через селект/полл и не нужны блокировки. Пнул — получатели прочли, что-то сделали и пнули других в ответ.

deep-purple ★★★★★
()
Ответ на: комментарий от pihter

Если нужно время события - можно записать в переменную время события;-)

Я не программист, я знаю тока два варианта - коллбэк (скажем по сигналу, я че то там никаких жутких траблов не видел) или сам смотришь когда руки дошли не пришло ли че нить в ящик/очередь/файл/…

Все остальное КМК к этим двум случаям сводится.

AntonI ★★★★★
()
Ответ на: комментарий от deep-purple

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

А Вы продолжайте фантазировать и фонтанировать пайпами, 20 процессов каждый-с-каждым сколько пайпов потребует?

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Пока это основной план

pihter ★★★★★
() автор топика
Ответ на: комментарий от AntonI

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

deep-purple ★★★★★
()
Ответ на: комментарий от pihter

событие через ШМ никак.

все еще непонятна природа процессов слушателей )

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

как связаны обычная деятельность процесса и команды, которые он обрабатывает?

olelookoe ★★★
()
Последнее исправление: olelookoe (всего исправлений: 1)
Ответ на: комментарий от deep-purple

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

А ты точно программист? Я нет, я тоже обычно так делаю, и меня за это настоящие программисты ругают;-)

AntonI ★★★★★
()
Ответ на: комментарий от olelookoe

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от AntonI

А ты точно программист? Я нет, я тоже обычно так делаю, и меня за это настоящие программисты ругают;-)

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

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

deep-purple ★★★★★
()
Ответ на: комментарий от pihter

Рыбак рыбака… вот подарок, это лучше принтфов:

	//--------------------------------------------------------------------------
	struct SplitArgForOut{
		int end, next;
		SplitArgForOut(const char *str){
			const char *br = "()[]{}"; int brc[3] = {0, 0, 0};
			for(end=0; str[end] && (brc[0] || brc[1] || brc[2] || str[end]!=','); ++end)
				for(int k=0; k<6; ++k) if(str[end]==br[k]){ brc[k/2] += 1-k%2*2; break; }
			next = str[end]?end+1:end; while(str[next] && (str[next]==' ' || str[next]=='\t')) next++;
		}
	};
	//--------------------------------------------------------------------------
	inline void debug_out(std::ostream&, const char*){}
	template <typename T, typename ... Args> void debug_out(std::ostream& out, const char* str, T x, Args ... args){
		SplitArgForOut key(str);
		if(str[0]!='"'){ out.write(str, key.end); out<<"="; }
		out<<x; if(sizeof...(Args)>0) out<<", ";
		debug_out(out, str+key.next, args...);
	} 
	//--------------------------------------------------------------------------
#define WMSG(args...) { std::cerr<<"#"<<__FILE__<<" "<<__FUNCTION__<<"() "<<__LINE__<<": ";	\
		debug_out(std::cerr, #args, args); std::cerr<<"\n"; }

юзать так

WMSG(a, b, a+b); // любое число аргументов

выводит файл, функцию, номер строки и дальше значения аргументов в виде a=…, b=…, a+b=…

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от pihter

10-20 штук, топология – каждый с каждым, желательно без сервера

Это уже больше похоже на event loop или actor model. Большое число потоков/процессов – это и большое число переключения контекста.

Сообщения вида: измени такую-то свою переменную

Блин, точно на акторную модель похоже :)

Попробуй SObjectizer или тому подобное. Может часть задачи на нём будет решаться легче. Как минимум код станет проще, без всяких мютексов, сокетов, ожиданий. На уровне: если пришло такое-то сообщение, то сделать это. А всё остальное возьмёт на себя рантайм. Хотя тогда из нескольких процессов/потоков надо будет сделать одно приложение.

ZMQ - хорошая обвязка над сокетами. Но потоки, ожидания, poll никуда не денутся, хотя что-то скроется, в том числе переподключения.

Всякие MQ с брокерами (аля, MQTT), позволят контролировать доставку сообщений более аккуратно. Например, подключившемуся клиенту прислать последнее сообщение с топика foo/config/xyz.

AlexVR ★★★★★
()

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

alysnix ★★★
()
Ответ на: комментарий от pihter

ну тогда зачем отдельный(е) треды?

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

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

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

реализовать можно по всякому, но, пожалуй, через стандартный message queue было бы проще всего. если хочется непременно руками и не как у всех ) а так - rabbitmq, например.

olelookoe ★★★
()
Последнее исправление: olelookoe (всего исправлений: 1)
Ответ на: комментарий от deep-purple

в любом раскладе нужен отдельный процесс с очередью сообщений

Да нет же. Я придумал как без демона, нафиг мне точка отказа?

pihter ★★★★★
() автор топика
Ответ на: комментарий от AntonI

выводит файл, функцию, номер строки и дальше значения аргументов в виде a=…, b=…, a+b=…

Так это ж макросом над принтфом делается… спасибо, в любом случае за подарок

pihter ★★★★★
() автор топика
Ответ на: комментарий от alysnix

Ну для себя, в смысле, для души – это да. Но, вообще-то, это в прод )

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

Над принтфом сложнее, там надо %букофка-правильная угадывать в зависимости от типа аргумента. Я сам принтф больше люблю чем iostream, но вот в таких вещах iostream рулит.

Эта штука для отладочной печати просто незаменима.

AntonI ★★★★★
()
Ответ на: комментарий от pihter

Не спорь с человеком считающим себя Настоящим Программистом - он лучше знает как надо (но не понимает что именно надо;-)))).

AntonI ★★★★★
()
Ответ на: комментарий от olelookoe

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

ну у меня хоть и большинство – серверные, все же – не все. Всем переписывать главный цикл – ну его. Обязательно что-нибудь где-нибудь отвалится. Это местами очень суровый легаси. Я там в глубинах код подписанный 2002 годом находил )

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

ну так я что-то вроде того и изобретаю

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

у меня есть сомнения в необходимости отдельного процесса

pihter ★★★★★
() автор топика
Ответ на: комментарий от olelookoe

если хочется непременно руками и не как у всех

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Обещаю попробовать! Ну как понравится

pihter ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Да чего ты на него взъелся? Он, вроде, ничего дурного тебе не говорил. ИМХО, у вас недопонимание.

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

И как без демона?

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

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

Да чего ты на него взъелся? Он, вроде, ничего дурного тебе не говорил. ИМХО, у вас недопонимание.

Сегодня не говорил но раньше много говорил;-( Он еще не дошел до состояния когда лучше игнорить, но у меня сегодня немного глумливое настроение;-)

Прости пожалуйста, виноват, больше не буду портить хороший тред.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.