Unix аналог цикла сообщений Windows
От: AlexGin Беларусь  
Дата: 04.01.25 08:50
Оценка: :))
Доброго времени суток, уважаемые коллеги, с наступившим Новым 2025 Годом

В процессе творческих поисков я наткнулся на тот факт, что работая под Windows (WinAPI & MFC) я нередко применял отправку сообщения потоку выполнения:

PostThreadMessage

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postthreadmessagea

Вот как в потоке исполнения "принять" это сообщение:
    MSG msg;
    while(GetMessage(&msg,0,0,0))
    {
        if(msg.message == WM_APP+1)
        {
            MessageBoxA(NULL,"Hello","From Thread",MB_OK);
        }
        DispatchMessage(&msg);
    }

https://www.codeproject.com/Articles/225755/PostThreadMessage-Demystified

Мог ли бы кто-нибудь подсказать мне — что же в Unix (Linux) системах соответствует всему вышеперечисленному?

Гугление — привело меня к статье:
http://www.linuxfocus.org/Russian/March2003/article287.shtml
Но я не уверен — в том ли направлении копаю?

Заранее благодарен, за любые подсказки!
Re: Unix аналог цикла сообщений Windows
От: kov_serg Россия  
Дата: 04.01.25 09:32
Оценка: +1
Здравствуйте, AlexGin, Вы писали:

AG>PostThreadMessage

AG>https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postthreadmessagea

AG>Вот как в потоке исполнения "принять" это сообщение:

AG>
AG>    MSG msg;
AG>    while(GetMessage(&msg,0,0,0))
AG>    {
AG>        if(msg.message == WM_APP+1)
AG>        {
AG>            MessageBoxA(NULL,"Hello","From Thread",MB_OK);
AG>        }
AG>        DispatchMessage(&msg);
AG>    }
AG>

AG>https://www.codeproject.com/Articles/225755/PostThreadMessage-Demystified

AG>Мог ли бы кто-нибудь подсказать мне — что же в Unix (Linux) системах соответствует всему вышеперечисленному?


Display* display;
XEvent event[1];
int quited=0;
...
while(!quited) {
   XNextEvent(display,event);
   switch(event->type) {
        ...
   }
}
https://tronche.com/gui/x/xlib/

А если просто межпроцессорное взаимодействие то https://tldp.org/LDP/tlk/ipc/ipc.html
Но своему потоку можно кучей способов отправлять сообщения, у вас же есть мутексы семафоры и другие механизмы синхронизации.

Но если хочетмя System V message queue то вас никто не останавливает
Отредактировано 04.01.2025 9:34 kov_serg . Предыдущая версия .
Re: Unix аналог цикла сообщений Windows
От: _NN_  
Дата: 04.01.25 09:41
Оценка:
Здравствуйте, AlexGin, Вы писали:

AG>Доброго времени суток, уважаемые коллеги, с наступившим Новым 2025 Годом

С Новым Годом!

А цель какая?
Передать данные из потока в поток ?
Тут полно вариантов от примитивных с message queue, pipe до готовых библиотек.
А вообще передавать сообщения таким образом как вы предлагали в Windows подходит только если нужно передать до 2х чисел и только если требуется блокировать очередь сообщений интерфейса, что обычно как раз и не нужно.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Unix аналог цикла сообщений Windows
От: Pzz Россия https://github.com/alexpevzner
Дата: 04.01.25 10:18
Оценка: 2 (1)
Здравствуйте, AlexGin, Вы писали:

AG>Мог ли бы кто-нибудь подсказать мне — что же в Unix (Linux) системах соответствует всему вышеперечисленному?


Нету такого.

Существует 100500 способов что-нибудь в таком духе организовать, но готового общесистемного механизма, напоминающего вендовые (оконные) сообщения в UNIX нет.

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

AG>Гугление — привело меня к статье:

AG>http://www.linuxfocus.org/Russian/March2003/article287.shtml
AG>Но я не уверен — в том ли направлении копаю?

Использовать внутри процесса для общения между потоками системные вызовы — это как-то перебор IMHO. А SysV API изначально не был слишком удачным, и я не вижу особого смысла вообще его использовать в современном (не отягощённом legacy) коде.
Re[2]: Unix аналог цикла сообщений Windows
От: AlexGin Беларусь  
Дата: 04.01.25 10:58
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>А цель какая?

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

_NN>Передать данные из потока в поток ?

Это также, но это не самоцель — тут можно и мьютексом защититься, чтобы избежать гонок.

_NN>Тут полно вариантов от примитивных с message queue, pipe до готовых библиотек.

Да именно — message queue

_NN>А вообще передавать сообщения таким образом как вы предлагали в Windows подходит только если нужно передать до 2х чисел...

Как я уже писал — передать числа — не самоцель. Скорее — ожидание с прокачкой сообщений.
Re[3]: Unix аналог цикла сообщений Windows
От: Pzz Россия https://github.com/alexpevzner
Дата: 04.01.25 11:09
Оценка: 8 (3) +2
Здравствуйте, AlexGin, Вы писали:

_NN>>А цель какая?

AG>Прокачать сообщения из системной очереди. Это не равносильно тому, что просто подождать.

В UNIX нет системной очереди сообщений.

Вообще, наличие этой очереди — это артефакт организации графической подсистемы в Windows, еще со времён Win 1.0. Потом этот механизм к потокам притянули.

В UNIX, традиционн, графическая подсистема не является частью ОС, а реализована в user space, на правах обычной задачи. Соответственно, артефактами своими операционную систему она не обогащает.
Re: Unix аналог цикла сообщений Windows
От: Слава  
Дата: 04.01.25 13:39
Оценка: 6 (2) +1
Здравствуйте, AlexGin, Вы писали:

AG>Заранее благодарен, за любые подсказки!


Вы спросили про сообщения винды, которые в винде используются почти что исключительно для рисования графического интерфейса. Для полного аналога вам надо искать сведения про Xorg и Wayland, я уверен, аналог у них есть.

Вот hello world для Xorg https://literateprograms.org/hello_world__c__xlib_.html

Если же вам нужны сообщения вообще, а не оконные, то в линуксе существует некий msgget и вообще message queue, но почему-то их использование у людей вызывает вопросы: https://stackoverflow.com/questions/10045015/why-is-there-no-poll-select-like-mechanism-for-message-queue Ещё в линуксе есть linux domain socket, это особый тип файла в обычной файловой системе, подобие named pipe. Это обычный поток байт, границы сообщений надо делать самому, в отличие от виндовых named pipes, которые умеют работать в двух режимах — потоковом и с разбиением на сообщения. Большое преимущество этих сокетов перед named pipes — это нормальный путь к сокету, вместо \\.\pipe\PipeName

Вообще в линуксе, в отличие от винды, не было изначально единого понятия "объект синхронизации", поэтому разные типы объектов IPC требуют разных методов для ожидания на них. И разные методы частично дублируют друг друга, например condition variable, которое pthread_cond_init в принципе похоже на eventfd, только на condition variable вы не сможете ожидать в epoll, а вот на eventfd сможете. Вроде как были методы для создания обёрток от одних объектов к другим, но сходу я этого найти не могу.

В винде тоже есть проблемы, например крутить цикл опроса оконных сообщений и одновременно ожидать ввода-вывода на IOCP в одном и том же треде неожиданно сложно, и даже невозможно вплоть до Windows 10 https://stackoverflow.com/questions/48236826/waiting-for-gui-events-and-iocp-notifications-at-once , а с минимум двумя тредами всё куда проще. В линуксе сделать оконный цикл и IO-цикл в одном и том же треде должно быть частично проще, чем в винде, поскольку оконные сообщения Xorg приходят через точно такой же сокет, как и сетевые события https://stackoverflow.com/questions/68629653/poll-x-events-via-file-descriptor-or-socket
Re: Unix аналог цикла сообщений Windows
От: andrey.desman  
Дата: 04.01.25 15:10
Оценка: -1 :)
Здравствуйте, AlexGin, Вы писали:

AG>Мог ли бы кто-нибудь подсказать мне — что же в Unix (Linux) системах соответствует всему вышеперечисленному?


В линуксе, как и в виндовсе, в простейшем варианте на плюсах используют mutex, condition_variable и любой угодный контейнер для очереди сообщений.
Если вариант не простейший, то нужны детали.
Re: Unix аналог цикла сообщений Windows
От: r0nd  
Дата: 04.01.25 20:21
Оценка: 2 (1)
On Jan 4, 2025, 11:50 AM, AlexGin <21902@users.rsdn.org> wrote:

AG>что же в Unix (Linux) системах соответствует всему вышеперечисленному?;


Для (GTK / PPC64 and PPC64LE) будет как-то так:
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdbool.h>

int main(int argc, char *argv[]) {
    
    gtk_init(&argc, &argv);

    
    while (true) {
        
        // примерно аналог вашего while(GetMessage(&msg,0,0,0))
        while (gtk_events_pending()) {
            
            // аналог DispatchMessage
            gtk_main_iteration_do(false);
        }
        
        
        g_usleep(100000);
        
    }


GTK сам по себе не поддерживает аналоги PostThreadMessage. Для пользовательских сообщений можно использовать:
…≪ Dementor 1.7.5 ✪ Lets Play a Game ⚀⚁⚁⚄⚄ ≫
Re: Unix аналог цикла сообщений Windows
От: Conductor СССР  
Дата: 07.01.25 19:27
Оценка: 4 (1)
Здравствуйте, AlexGin, Вы писали:

AG>Мог ли бы кто-нибудь подсказать мне — что же в Unix (Linux) системах соответствует всему вышеперечисленному?


Ну, насколько я понимаю, такие вопросы возникают при портировании win-кода, где прокачка сообщений использовалась для того, чтобы не морозить GUI-поток (типа повесили окно с а-ля "Выполняется длительная операция...", и либо ждём, периодически прокачивая сообщения, пока другой поток завершит работу, либо в этом же потоке между прокачками сообщений выполняем некую затратную по времени работу).
Реализация аналога зависит от того, что используется в программе. Чем мы заткнули: если Qt — вообще без проблем (варианты: QCoreApplication::processEvents(), QMetaObject::invokeMethod()), если без Qt — asio. (Ну а если с gstreamer'ом работа, то GstBus.)
Отредактировано 07.01.2025 19:37 Conductor . Предыдущая версия .
Re[2]: Unix аналог цикла сообщений Windows
От: AlexGin Беларусь  
Дата: 09.01.25 05:18
Оценка:
Здравствуйте, Conductor, Вы писали:

C>Ну, насколько я понимаю, такие вопросы возникают при портировании win-кода,

+100500

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

C>Реализация аналога зависит от того, что используется в программе. Чем мы заткнули: если Qt — вообще без проблем (варианты: QCoreApplication::processEvents(), QMetaObject::invokeMethod()), если без Qt — asio. (Ну а если с gstreamer'ом работа, то GstBus.)

Да, в Qt проблем нет: там есть всё, что ты указал — да и просто connect с постановкой сообщения в очередь: Qt::QueuedConnection.
Меня интересует вариант именно тогда, когда без Qt.

Что применять в этом случае? Возможно, есть современное решение?

Тянуть с собой громоздзкий boost — ИМХО так себе идея.

P.S. Когда-то много пользовался boost-ом, но теперь — не вижу смысла к нему прибегать.
Тем более, если нам нужно просто asio.
Re: Unix аналог цикла сообщений Windows
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.01.25 07:43
Оценка:
Здравствуйте, AlexGin, Вы писали:

Не совсем то, но в .Net есть асинхронная очередь AsyncProducerConsumerCollection

Привязка к объекту синхронизации через SynchronizationContext
и солнце б утром не вставало, когда бы не было меня
Re[3]: Unix аналог цикла сообщений Windows
От: Conductor СССР  
Дата: 09.01.25 18:57
Оценка:
Здравствуйте, AlexGin, Вы писали:

AG>Меня интересует вариант именно тогда, когда без Qt.

AG>Что применять в этом случае? Возможно, есть современное решение?

Ну, тут ведь как это ни банально звучит, от целей и задач всё зависит — от стратегии и тактики:
1. Старый win-код нужно сохранить/трогать по минимуму? (Необходимо будет собирать и для win, и для lin?)
2. Говорим о GUI-программе? (Потому что если не GUI, то вообще средствами языка можно обойтись.)
3. Если GUI, то какой framework используется, что он предлагает для работы в логике сообщений?
И т.д.

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

По поводу asio. Ну, во-первых, можно использовать и без boost. А во-вторых: а что, собственно, такого уж громоздкого в boost – что надо используй в проекте (хоть header-only), что не надо – не используй. Остальное лежит себе на машине разработчика, каши есть не просит. Кроссплатформенно, опять же. Если проект с cmake, то задействовать boost вообще – 2-3 строчки.

Upd. Сейчас увидел, что ты GNOME используешь, если про GUI говорим — по glib документацию не смотрел? Например, начиная отсюда:
The Main Event Loop: GLib Reference Manual
Отредактировано 09.01.2025 19:06 Conductor . Предыдущая версия .
Re[4]: Unix аналог цикла сообщений Windows
От: AlexGin Беларусь  
Дата: 09.01.25 20:43
Оценка:
Здравствуйте, Conductor, Вы писали:

C>Здравствуйте, AlexGin, Вы писали:


AG>>Меня интересует вариант именно тогда, когда без Qt.

AG>>Что применять в этом случае? Возможно, есть современное решение?

C>Ну, тут ведь как это ни банально звучит, от целей и задач всё зависит — от стратегии и тактики:

C>1. Старый win-код нужно сохранить/трогать по минимуму? (Необходимо будет собирать и для win, и для lin?)
Да.

C>2. Говорим о GUI-программе? (Потому что если не GUI, то вообще средствами языка можно обойтись.)

Нет. Здесь речь скорее о CLI-приложении. Или даже о системной службе (демоне).
В программе с GUI я бы без вопросов всё это закрыл на Qt.

C>3. Если GUI, то какой framework используется, что он предлагает для работы в логике сообщений?

Ещё раз подчеркну — этот вопрос относится к работе приложений командной строки.

C>Если бы задача в целом и окружение были более полно обозначены, то и обсуждать было бы проще.

Пока подробности проекта не прорисовались — но я уже что-то намечаю.

C>По поводу asio. Ну, во-первых, можно использовать и без boost. А во-вторых: а что, собственно, такого уж громоздкого в boost – что надо используй в проекте (хоть header-only), что не надо – не используй.

Я в курсе, что boost в основном header-only. В курсе, что замусоривает диск у разработчика.
Да и какой смысл — тащить всё ради asio...

C>Остальное лежит себе на машине разработчика, каши есть не просит. Кроссплатформенно, опять же. Если проект с cmake, то задействовать boost вообще – 2-3 строчки.

Да, проект с применением CMake.
Ясно, cпасибо, подумаю и над этим вариантом.

C>Upd. Сейчас увидел, что ты GNOME используешь, если про GUI говорим — по glib документацию не смотрел? Например, начиная отсюда:

C>The Main Event Loop: GLib Reference Manual

Спасибо за подсказку! Обязательно посмотрю!
Но ограничиваться только гномом как-то ИМХО не правильно.
Отредактировано 09.01.2025 21:30 AlexGin . Предыдущая версия . Еще …
Отредактировано 09.01.2025 20:45 AlexGin . Предыдущая версия .
Re[5]: Unix аналог цикла сообщений Windows
От: Conductor СССР  
Дата: 09.01.25 23:16
Оценка: 4 (1) +1
Здравствуйте, AlexGin, Вы писали:

C>>1. Старый win-код нужно сохранить/трогать по минимуму? (Необходимо будет собирать и для win, и для lin?)

AG>Да.

Сдаётся мне, что ваша ситуация чем-то похожа на нашу: была win-only система, которую после некоторых событий нужно было сделать кроссплатформенной. Я прав?
В этом случае максимально удобным оказался, естественно, подход, когда специфичные для платформы вызовы не разбросаны по коду, а локализованы в компонентах-обёртках (на начало работы над кроссплатформой у нас так было процентов на 90, в том числе и код, подобный тому, который ты приводил, был в отдельном компоненте).

C>>2. Говорим о GUI-программе? (Потому что если не GUI, то вообще средствами языка можно обойтись.)

AG>Нет. Здесь речь скорее о CLI-приложении. Или даже о системной службе (демоне).
AG>В программе с GUI я бы без вопросов всё это закрыл на Qt.
AG>Пока подробности проекта не прорисовались — но я уже что-то намечаю.

Если приложение новое и не-GUI, то условный «обмен сообщениями» сейчас добавляем только в том случае, если того требует используемый framework/библиотека и, соответственно, тот, который там используется (web-сервер на базе boost.beast – asio, естественно, gstreamer – его GstBus, который по факту glib), в остальных случаях стараемся обойтись средствами языка.

C>>По поводу asio. Ну, во-первых, можно использовать и без boost.

AG>Да и какой смысл — тащить всё ради asio...

C>>Upd. Сейчас увидел, что ты GNOME используешь, если про GUI говорим — по glib документацию не смотрел? Например, начиная отсюда:

C>>The Main Event Loop: GLib Reference Manual

AG>Спасибо за подсказку! Обязательно посмотрю!

AG>Но ограничиваться только гномом как-то ИМХО не правильно.

Да в том-то и дело, что нет тут ограничения, просто glib для gnome родной, но это отнюдь не значит, что не будет работать не в gnome. Опять же в качестве примера: мой дорогой во всех смыслах этого слова gstreamer – glib'овский, но работает везде, и Qt, в частности, его с удовольствием в QtMultimedia использует. Другой вопрос, что glib не всем, скажем так, нравится (вон коллега Marty сильно плевался с glib поработав), т.к. C-интерфейс, но ничего – в smart-pointer'ы оборачиваешь, лямбды присобачиваешь и можно жить более-менее удобно.
Re[5]: Unix аналог цикла сообщений Windows
От: flаt  
Дата: 10.01.25 04:00
Оценка: +1
Здравствуйте, AlexGin, Вы писали:


C>>2. Говорим о GUI-программе? (Потому что если не GUI, то вообще средствами языка можно обойтись.)

AG>Нет. Здесь речь скорее о CLI-приложении. Или даже о системной службе (демоне).
AG>В программе с GUI я бы без вопросов всё это закрыл на Qt.

Откуда в CLI взялся цикл сообщений? Говнокод какой-то. Выкинуть и переписать нормально — станет лучше и под windows, и в Linux легче портировать будет.
Re[6]: Unix аналог цикла сообщений Windows
От: AlexGin Беларусь  
Дата: 10.01.25 05:27
Оценка:
Здравствуйте, Conductor, Вы писали:

C>Здравствуйте, AlexGin, Вы писали:


C>>>1. Старый win-код нужно сохранить/трогать по минимуму? (Необходимо будет собирать и для win, и для lin?)

AG>>Да.

C>Сдаётся мне, что ваша ситуация чем-то похожа на нашу: была win-only система, которую после некоторых событий нужно было сделать кроссплатформенной. Я прав?

+100500

C>В этом случае максимально удобным оказался, естественно, подход, когда специфичные для платформы вызовы не разбросаны по коду, а локализованы в компонентах-обёртках (на начало работы над кроссплатформой у нас так было процентов на 90, в том числе и код, подобный тому, который ты приводил, был в отдельном компоненте).

Авторов разработки уже нет в досягаемости, а вызова специфичные для платформы — размазаны по всему коду

C>>>2. Говорим о GUI-программе? (Потому что если не GUI, то вообще средствами языка можно обойтись.)

Да, похоже здесь ты прав.

C>Если приложение новое и не-GUI...

Там получается целый набор приложений. С приложениями с GUI — есть понимание: применять Qt.
Что касается приложений без GUI — картинка как-то всё же прорисовалась.
В общем — тему можно закрывать

C>...«обмен сообщениями» сейчас добавляем только в том случае, если того требует используемый framework/библиотека и, соответственно, тот, который там используется (web-сервер на базе boost.beast – asio, естественно, gstreamer – его GstBus, который по факту glib), в остальных случаях стараемся обойтись средствами языка.

+100500

AG>Но ограничиваться только гномом как-то ИМХО не правильно.


C>Да в том-то и дело, что нет тут ограничения, просто glib для gnome родной, но это отнюдь не значит, что не будет работать не в gnome. Опять же в качестве примера: мой дорогой во всех смыслах этого слова gstreamer – glib'овский, но работает везде, и Qt, в частности, его с удовольствием в QtMultimedia использует. Другой вопрос, что glib не всем, скажем так, нравится (вон коллега Marty сильно плевался с glib поработав), т.к. C-интерфейс, но ничего – в smart-pointer'ы оборачиваешь, лямбды присобачиваешь и можно жить более-менее удобно.

+100500
Посмотрю в эту сторону! Спасибо!
Re[6]: Unix аналог цикла сообщений Windows
От: AlexGin Беларусь  
Дата: 10.01.25 05:30
Оценка:
Здравствуйте, flаt, Вы писали:

F>Откуда в CLI взялся цикл сообщений? Говнокод какой-то. Выкинуть и переписать нормально — станет лучше и под windows, и в Linux легче портировать будет.


Да, уже некоторое осмысление пришло. Спасибо.
Тему можно закрывать
Re[3]: Unix аналог цикла сообщений Windows
От: Философ Ад http://vk.com/id10256428
Дата: 10.01.25 06:21
Оценка:
Здравствуйте, AlexGin, Вы писали:

_NN>>Тут полно вариантов от примитивных с message queue, pipe до готовых библиотек.

AG>Да именно — message queue

Я для виндовой проги писал свою очередь — во-первых, не понимал как это будет работать в сервисах, а во-вторых, большинство разработчиков в конторе не знали об очереди виндовых сообщений и для них код на их основе был бы сюрпризом, тем более если бы кто-нибудь использовал SendMessage вместо PostMessage — матом бы меня крыли до сих пор. Кроме того, код на основе виндовых сообщений почти не поддаётся тестированию: написать юнит-тесты для такого — задача не из лёгких.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[2]: Unix аналог цикла сообщений Windows
От: Философ Ад http://vk.com/id10256428
Дата: 10.01.25 06:30
Оценка:
Здравствуйте, Слава, Вы писали:

С>...Большое преимущество этих сокетов перед named pipes — это нормальный путь к сокету, вместо \\.\pipe\PipeName


А что не так с именами пайпов в винде? Для меня это привычно и нормально. Какие пути к сокету в юниксе — сорри, гуглить сейчас лень.
Всё сказанное выше — личное мнение, если не указано обратное.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.