Как получить сообщение всем потокам?

139
22 августа 2021, 20:20

Например я получаю из очереди сообщение и хочу его разослать всем потокам. Я думал про общую память, но вроде вдруг не все потоки успеют использовать сообщение из общей памяти. А если использовать очередь, то только один поток получает сообщение.

Как быть? Может я чего то не знаю, неужели невозможно отправить типа broadcast какого нибудь.

Для чего это мне нужно. Я пока рассматриваю так. У моей программы есть unix socket, если к нему подключается клиент, то создаётся отдельный поток, и вот для этого мне и нужно рассылать всем потокам сообщение, чтобы поток мог клиенту отправить в unix сокет сообщение.

Или лучше не так делать?

Answer 1

А если использовать очередь, то только один поток получает сообщение.

Но это можно победить. Наверное, вы знаете, что в Linux поддержвается два типа очередей сообщений. Для конкретности, давайте будем говорить о очередях System V. Там предполагается, что сообщение имеет тип такой структуры:

/* message buffer for msgsnd and msgrcv calls */
struct msgbuf {
        long mtype;         /* type of message */
        char mtext[1];      /* message text */
};

Обратите внимание на поле mtype. Если к очереди "прицеплено" несколько абонентов, то это поле можно использовать в качестве адреса получателя. Т.е. каждый процесс знает свой адрес (например - pid), а отправитель этот адрес указывает в сообщении.

Тогда получатель, используя вызов

msgrcv(msqid, msgp, msgsz, mtype, msgflg); // mtip - мой адрес

получит только сообщения, адресованные конкретно ему. Легко придумать "широковещательный" адрес в очереди сообщений. Например -1.

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

struct msgbuf {
        long mtype;         /* type of message */
        long num_rec;       /* Количество получателей данного сообщения */
        char mtext[1];      /* message text */
};

Для "одноадресного" сообщения в поле num_rec пишем единичку. Если же сервер желает отправить "широкополосное" сообщение всем клиентам, то он задаёт в этом поле число присоединившихся клиентов.

Клиент, получив сообщение с "широкополосным" адресом, декрементирует это поле и, если оно всё еще > 0, немедленно помещает его обратно в очередь сообщение.

Вот и весь алгоритм.

READ ALSO
аналог unix socket в windows

аналог unix socket в windows

Есть ли аналог unix socket в windows? Типа такого как в линукс и unix

126
Как заменить символ в строке?

Как заменить символ в строке?

Задача: Надо написать функцию который находит в строке цифры и заменяет их на десятичные кодыНапример "aaa'6'xxx" на "aaa54xxx"

84
Ошибка подключения клиента к серверу TCP/IP

Ошибка подключения клиента к серверу TCP/IP

не могу создать соединение между сервером и клиентом по tcp/ip на Linux MintКомпилирую через gcc

158
Почему значение возвращается либо в экспоненциальной форме, либо возвращается 0

Почему значение возвращается либо в экспоненциальной форме, либо возвращается 0

Первый вопрос: почему если не указать fixed значение вернется в экспоненциальной форме? Второй вопрос: почему если поставить fixed, то вернется...

72