LINUX.ORG.RU

Не удается запустить механизм Mqueue

 , , ,


1

1

Хочу освоить для одной задачи механизм Mqueue, это стандартный POSIX механизм IPC, который показался мне интересным. Отсоветуйте, если считаете его плохим, но он есть и на QNX 4 и на Linux, поэтому это портабельное решение для меня выходит.

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

Проблема вот в чем: не удается увидеть работу этого механизма, я явно что то делаю не так. Запускается сервер, открывается очередь под именем, под QNX 4 хотя бы открывается на сервере и клиенте, клиент что-то отправляет и это видно в статистике, сервер не видит данных. А под Linux попробовал - не работает и вовсе, канал не открывается.

Пробовал блокирующий и неблокирующий режим, но мне нужен неблокирующий - выстрелил и забыл. Далее код:

#include <stdio.h>
#include <mqueue.h>

char data[100000];

int main()
{
	mqd_t mq;
	struct mq_attr attr;
	int rc;

	attr.mq_flags = 0;
	attr.mq_maxmsg = 100;
	attr.mq_msgsize = 65536;
	attr.mq_curmsgs = 0;

	printf("test_mq_server\n");
	//mq = mq_open("/sqlite_sdb", O_CREAT | O_RDWR | O_NONBLOCK, 0660, &attr);
	mq = mq_open("/sqlite_sdb", O_CREAT | O_RDONLY, 0660, &attr);
	printf("mq opened, server mq= %d\n", mq);

	while(1)
	{
		rc = mq_receive(mq, data, 65536, NULL);
		printf("server rc= %d\n", rc);
		sleep(1);
	}

	mq_close(mq);
	mq_unlink("/sqlite_sdb");
	return 0;
}
#include <stdio.h>
#include <mqueue.h>

int main()
{
	mqd_t mq;
	char data[100000];
	int rc, i;

	printf("test_mq_client\n");
	//mq = mq_open("/sqlite_sdb", O_RDWR | O_NONBLOCK);
	mq = mq_open("/sqlite_sdb", O_WRONLY);
	printf("client mq= %d\n", mq);
	for(i = 0; i < 3; i++)
	{
		rc = mq_send(mq, "test_mq", 7, 0);
		printf("client rc= %d\n", rc);
		sleep(1);
	}
	mq_close(mq);
	//mq_unlink("/sqlite_sdb");
	return 0;
}

QNX4

test_mq_server
mq opened, server mq= 3
server rc= -1
server rc= -1
test_mq_client
client mq= 3
client rc= 0
server rc= -1
client rc= 0
server rc= -1
client rc= 0
server rc= -1
server rc= -1

Linux

test_mq_server
mq opened, server mq= -1
server rc= -1
server rc= -1
итого 0

------ Очереди сообщений --------
ключ   msqid      владелец права исп. байты сообщения
0x331100ea 0          root       622        0            0           

test_mq_client
client mq= -1

client rc= -1
------ Очереди сообщений --------
ключ   msqid      владелец права исп. байты сообщения
0x331100ea 0          root       622        0            0           

server rc= -1
client rc= -1
server rc= -1
client rc= -1
server rc= -1
server rc= -1
server rc= -1

Запускалось так

./test_mq_server &
sleep 1
./test_mq_client &
sleep 5

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

Под QNX4 хотя бы очереди открываются, а под Linux нет. Что-то надо запустить? Или модуль ядра запустить?

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

Я долго бился прежде чем нашел пример, вот этот у меня заработал: https://stackoverflow.com/questions/3056307/how-do-i-use-mqueue-in-a-c-program-on-a-linux-based-system

Работает как на QNX4 так и на Linux.

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

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от I-Love-Microsoft

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

Из любопытства, проверил под фряхой (угу, пришлось сделать kldload mqueuefs). Короче, если урезать размер принимаемого буфера с 65536 до 10000 — работает, как предполагается. Окажи любезность, проверь у себя.

anonymous ()
Ответ на: комментарий от Deleted

Кстати, в QNX4 настройка сервера этого механизма говорит что это число лишь дефолт, и если сервер открывает очередь с иным параметром, оно принимает большее значение. А вот в Linux это видимо действительно максимум.

I-Love-Microsoft ★★★★★ ()

На всякий:

  • если в libmdbx работать с БД в режиме MDBX_WRITEMAP + MDBX_UTTERLY_NOSYNC то получишь аналог mqueue с дополнительным набором плюшек.
  • «sqlite» намекает на использование mqueue для общения с БД, если так то можно посмотреть на libfpta где есть БД с «табличками, колонками и индексами» с прямым доступом из нескольких процессов, но БЕЗ sql.
  • на QNX сам я это не гонял, но поправлю за день-два если будут проблему со сборкой или глюки.
Deleted ()
Ответ на: комментарий от Deleted

Чуток запарился, поправлюсь:

  • аналог mqueue будет в режиме MDBX_UTTERLY_NOSYNC.
  • а MDBX_WRITEMAP добавит скорости, но позволит «расписать» данные в случае ошибочной работы с указателями.
Deleted ()
Ответ на: комментарий от I-Love-Microsoft

Ты меня не понял. В показанном тобой коде есть mq_open("/sqlite_sdb"..., что намекает на намерение использовать mqueue для общения c «сервером» SQLite.

Deleted ()
Ответ на: комментарий от anonymous

Проверил на QNX4, сервер Mqueue -s 75000 но сервер открывается лишь при величине пакета 32000, а мне надо 65536 и даже немного больше. Структура attr никак не должна ограничиваться, там для длины пакетов использован long.

Еще заметил вот что - число read_bytes всегда максимальное когда приходит пакет, я надеюсь оно не гоняет все 32000 байт когда я шлю всего 10 байт???

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от I-Love-Microsoft

У меня для базы Open Watcom 1.9, и он еле еле SQLite берет. А там в требования GCC 4.2, едва ли сожрет такую базу как libfpta.

Там нет каких-то мега требований. Должен прожевать с небольшими правками.

Что касается GCC 4.2, то я обычно в требования пишу минимальную версию компилятора, на которой получилось проверить по ходу разработки.

Ну и конечно в помощь Open Watcom стоит поставить какой-нибудь не сильно дремучий gcc.

Deleted ()

Тема решена. Mqueue говно. По непонятной причине отсутствует необходимая гибкость, невозможно сделать размер сообщений 70 килобайт под QNX4 (да даже больше 32 килобайт), при этом сами сообщения приходят максимальной длины и я не понимаю как получать их размер.

Короче, не подходит, придется для QNX4 Linux и прочих - делать враппер на наиболее удобные и надежные механизмы работы для каждой из платформ. В Linux это Unix domain socket (насколько понимаю, это просто как обычный интернет сокет только локальный, без оверхеда на сетевой протокол), в QNX4 стандартная хрень обмена сообщениями.

I-Love-Microsoft ★★★★★ ()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)