LINUX.ORG.RU

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

 ,


0

2

Смеркалось.

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

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

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

★★★★★

zmq, dbus

но сначала всё-таки определиться что посылаешь и зачем :-) Какой-то разброд и шатания - то ли сигналы, то ли сообщения..то ли в один адрес, толи в несколько. и так далее

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

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

zmq, dbus

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

но сначала всё-таки определиться что посылаешь и зачем :-)

это я уже!

Какой-то разброд и шатания - то ли сигналы, то ли сообщения..то ли в один адрес, толи в несколько. и так далее

Это я так описал широко: моя цель – не чтоб мне дали ответ что использовать, а послушать что люди об этом думают, кто что слышал, кто что использует. Опыт: был ваш – будет наш!

а чтобы не порождать треды на каждый чих

Тебе жалко что-ли? :) давай обсудим!

например libuv.org (и подобные, их много на вкус и цвет)

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

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

есть и асинхронные библиотеки, но там всё равно где-то создается этот отдельный thread.

И другого пути нет? Если так: то на кой черт мне эти библиотеки, я и без них могу тред создать и сидеть слушать сокет. 20 строчек делов и тащить ниче не надо и отлаживать проще. Мне главное – надежность и простота. И скорость. И какаво с чаем :) все хочу и нахаляву

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

В чём вопрос то тогда, если уже все можешь. С AF_UNIX, SOCK_SEQPACKET можно даже не думать о фреймах – read/write всегда будут получать нужный размер.

Путей 3: сокеты, сигналы, разделяемая память. Последние 2 правильно использовать крайне непросто.

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

А как ты ещё хотел? Типа, данные из сокета сами собой принимаются и ложатся и ложатся куда-то?

Ну есть же варианты: ждать сигнал, потом выгребать (отделный тред не нужен, плюс селект вот предложили. Все еще не так однозначно! )

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

В чём вопрос то тогда, если уже все можешь.

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

Путей 3: сокеты, сигналы, разделяемая память

А как через память передать событие? Именно пнуть другой процесс

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

В рамках хоста еще есть файлы на tmpfs.

Гуру говорят что сокеты самое Ъ, но я даже между хостами уже давно предпочитаю пайпы (cin/cout) поверх ssh, оно как то проще.

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

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

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

В рамках хоста еще есть файлы на tmpfs

Был бы еще способ просунуть через нее событие, а не данные…

Гуру говорят что сокеты самое Ъ, но я даже между хостами уже давно предпочитаю пайпы

Я тоже люблю минимально-простое и надежное.

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

да, оно, держу про запас как один из вариантов

В single-thread других-то особо и нет… Что-бы Вам не посоветовали - будет обёрткой вокруг этого (разной степени извращённости).

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

Ну есть же варианты: ждать сигнал, потом выгребать

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

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

В single-thread других-то особо и нет… Что-бы Вам не посоветовали - будет обёрткой вокруг этого (разной степени извращённости).

Ну, однопоточность – не священная корова для меня, просто не хотел плодить сущности. Будет проще через тред (а похоже – так и есть) – сделаю.

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

Будет проще через тред (а похоже – так и есть) – сделаю.

Well, если у Вас тысячи сокетов - тоже на каждый из них thread форкать будете? Так никто не делает.

ПыСы. Multi-thread это на голову сложнее, надо очень хорошо понимать во что Вы ввязываетесь, прежде чем.

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

Well, если у Вас тысячи сокетов - тоже на каждый из них thread форкать будете?

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

Так никто не делает

Ну вот я и спрашиваю :)

А чего дурного: запускаю программу, она создает тред слушатель, тот спокойно создает сокет и сидит слушает в блокировке, ресурсы не кушает. Данне пришли – выгреб и отдал колбеку в основную программу, пусть разбирается че там, а мы слушаем дальше. Напугай что может пойти не так (и обязательно пойдет), плиз.

Multi-thread это на голову сложнее, надо очень хорошо понимать во что Вы ввязываетесь, прежде чем.

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

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

А как на это колбек повесить? Сидети и читать раз в секунду так же в отдельном треде, а когда изменится – звать колбек? Ну такое себе (хотя бы потому что секунда тормозов)

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

Зачем в отдельном треде? В mainloop проверять файлы, если у кого то время поменялось и данные в нем валидны - обработать событие и запомнить новое время обновления.

Вставлять или не вставлять задержку это уже второй вопрос, я ж не знаю какие у Вас требования по латентности и т.д.:-)

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

И главное – надежность.

Поверьте - больше чем в single-thread её не будет. Сколько у Вас ядер на машинке? Макс 64-128. Не хотите Вы форкать threads сильно больше этого. Никогда.

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

А вообще клево, действительно – проще некуда и фиг сломаешь. Жалко что у меня доступа в главную петлю, как правило, нет чтоб там поллить, а так – огонь, одобряю.

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

Поверьте - больше чем в single-thread её не будет

Согласен.

Сколько у Вас ядер на машинке?

Джва )

Не хотите Вы форкать threads сильно больше этого.

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

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

Жалко что у меня доступа в главную петлю, как правило, нет

Тогда думать надо… и слушать что говорит @bugfixer, это его полянка.

Наверное надо ответить на следующие вопросы:

  1. число опрашиваемых процессов и топология (каждый с каждым взаимодействует, один со всеми, направление трафика данных)?

  2. характерная частота событий?

  3. сколько ресурсов (времени) надо для обработки одного события?

  4. какую максимальную латентность (задержку между событием и началом его обработки) надо обеспечить?

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

Как я понял тут вопрос как сделать проще а не как сделать шоб работало быстрее. На 15ти тредах которые в основном спят сильно не просядешь, веб-браузер сильно больше их генерит вроде бы.

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

число опрашиваемых процессов и топология (каждый с каждым взаимодействует, один со всеми, направление трафика данных)?

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

характерная частота событий?

Максимум – десяток в секунду

сколько ресурсов (времени) надо для обработки одного события?

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

какую максимальную латентность (задержку между событием и началом его обработки) надо обеспечить?

Не принципиально, но не секунду же :)

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

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

Каждый с каждым это реально разные данные двунаправленно в каждой паре ходят, или просто каждый машет ручкой остальным «всем поставить a=1», «всем поставить b=2»?

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

ПРи запуске приложения, которое должно уметь принимать «пинки» создавать тред (один) в котором тем или иным способом слушать какой-нибудь сокет/пайп/почередь_сообщений в блокирующем режиме, при приходе сообщения – вычитывать, звать колбек основного приложения, отдавать ему данные и вновь уходить на итерацию блокирующего чтения – ждать следующего сообщения

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

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

И? Какого порядка latency Вы пытаетесь добиться?

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

libuv.org

так там тот же поллинг + те же треды. Только там threadpool, т.е. треды создаются сразу на старте, а по отработке не умирают, а возвращаются в пул и висят на wait-е, если не нужны (из-за чего нет накладных расходов на старт/смерть тредов).

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

А чего дурного: запускаю программу, она создает тред слушатель, тот спокойно создает сокет и сидит слушает в блокировке, ресурсы не кушает.

Не забыть про таймаут на блокировке.

blex ★★
()

все зависит от нужд и потребностей принимающей стороны.

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

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

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

А в течении какого времени оно должно работать без остановки?

Так то модель КМК такая должна быть:

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

  2. каждый процесс следит за всеми остальными файлами, выцепляет оттуда то что относится к нему и обрабатывает. Проще всего это конечно делать в основном цикле, если это невозможно то… а почему это невозможно? Если скажем делать это в отдельном треде, то он все равно должен блокировать изменения переменных для основного цикла. То есть воткнуть в основный цикл поднятие/опускание блокировки можно, а вызов функции которая переменные перенастраивает нельзя? Второе кажется гораздо более простым…

AntonI ★★★★
()