Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 10.04.2020
Сообщений: 23

Обмен сообщениями между потоками с использованием функций PostThreadMessage и GetMessage

24.02.2022, 15:36. Показов 2698. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, помогите пожалуйста, первый раз с таким сталкиваюсь.

Написать программу, главный поток которой запускает несколько дополнительных потоков. Реализовать обмен сообщениями между главным и побочными потоками посредством передачи сообщений. Использовать функции CreateThread, PostThreadMessage, GetMessage. Как минимум, вторичные потоки должны посредством сообщений сообщать главный поток о своей готовности к работе и о завершении своего исполнения.

Я вот что-то намудрил, но почему то после 2ух сообщений ... thread has started. и ... thread has stopped. больше ничего не происходит, то есть как будто программа просто зависает в цикле while и больше не попадает во внешний цикл for и не создает новый поток. Я если честно понятия не имею, правильно ли это вообще. Помогите пожалуйста.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h>
#include <windows.h>
#include <iostream>
using std::cout;
using std::endl;
 
#define NUMBER_OF_THREADS 5
 
DWORD WINAPI ThreadFunc(void* param)
{
    DWORD main_thread = *((DWORD*)param);
    DWORD id = GetCurrentThreadId();
    
    PostThreadMessageA(main_thread, id, 1, 1);
 
    Sleep(1500); //Типо какая-то работа
 
    PostThreadMessageA(main_thread, id, 2, 1);
 
    return 0;
}
 
int main(int argc, char** argv)
{
    DWORD main_id = GetCurrentThreadId();
    HANDLE ThreadHandleArray[NUMBER_OF_THREADS];
 
    for (int i = 0; i < NUMBER_OF_THREADS; i++)
    {
        ThreadHandleArray[i] = CreateThread(NULL, 0, ThreadFunc, (void*)&main_id, 0, NULL);
 
        MSG msg;
        BOOL bRet;
 
        while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
        {
            if (bRet == -1) //Error
            {
                exit(1);
            }
            else
            {
                if (msg.wParam == 1)
                {
                    cout << msg.message << " thread has started." << endl;
                }
                else if (msg.wParam == 2)
                {
                    cout << msg.message << " thread has stopped." << endl;
                }
            }
        }
        WaitForSingleObject(ThreadHandleArray[i], INFINITE);
    }
    return 0;
}
Изображения
 
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.02.2022, 15:36
Ответы с готовыми решениями:

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

Как в boost обмениваться сообщениями между потоками?
Как в бусте обмениваться сообщениями между потоками? Обычно есть очереди или маилбоксы. Создаешь очередь/маилбокс для типа MyStruct и...

Обмен сообщениями между ServiceHost
Здравствуйте! Подскажите пожалуйста кто сталкивался с подобной задачей Вот часть (очень упрощённо сервисов) имеющихся которые имеют...

8
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
24.02.2022, 20:55
s2020mple, ты создаешь один поток и сразу запускаешь цикл обработки сообщений. До запуска остальных 4 потоков дело не доходит.

Добавлено через 7 минут
Цитата Сообщение от s2020mple Посмотреть сообщение
как будто программа просто зависает в цикле while и больше не попадает во внешний цикл for и не создает новый поток
Именно это и происходит. Основной поток зависает на GetMessage и ждет новых сообщений.
0
фрилансер
 Аватар для Алексей1153
6465 / 5679 / 1131
Регистрация: 11.10.2019
Сообщений: 15,121
24.02.2022, 21:24
s2020mple, PeekMessage - аналог, возвращающий управление без ожидания

Добавлено через 1 минуту

Не по теме:

если это не учебное задание, то потоки лучше гонять через std::thread, а виндовые сообщения заменить на синхронизированный вектор

0
0 / 0 / 0
Регистрация: 10.04.2020
Сообщений: 23
24.02.2022, 22:20  [ТС]
nonedark2008, А как можно добиться, чтобы основной поток не зависал на GetMessage и при этом дальше создавались новые потоки? Просто если поместить GetMessage после цикла с созданием потоков, то это теряет смысл, так как нужно, чтобы прям во время запуска и выполнения новые потоки сразу извещали об этом основной поток.

Добавлено через 2 минуты
Алексей1153, К сожалению учебное. Да, спасибо, с PeekMessage работает, а можно ли как-то добиться условия с использованием GetMessage? Просто в условии написано использовать именно GetMessage, а не PeekMessage.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
24.02.2022, 22:37
Цитата Сообщение от s2020mple Посмотреть сообщение
Просто если поместить GetMessage после цикла с созданием потоков, то это теряет смысл, так как нужно, чтобы прям во время запуска и выполнения новые потоки сразу извещали об этом основной поток.
Первое, тут можно поиграть вокруг "сразу". Потоки запускаются не мгновенно. Так что до их запуска основной поток вполне может успеть дойти до GetMessage.
Если хочется еще более "сразу", то обработку сообщений можно вынести в отдельный поток. В основном создаешь этот поток обработки сообщений, ждешь пока он запустится, а потом создаешь потоки, генерирующие сообщения.
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,113
24.02.2022, 22:39
Цитата Сообщение от s2020mple Посмотреть сообщение
А как можно добиться, чтобы основной поток не зависал на GetMessage и при этом дальше создавались новые потоки?
Ловите сообщение внутри цикла с GetMessage и запускайте потоки прямо в нём. Можете запускать новый поток по факту отлова сообщения об окончании работы потока. Или можете запустить таймер, ловить его оповещение в GetMessage и запускать из него потоки.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
25.02.2022, 12:21
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Так что до их запуска основной поток вполне может успеть дойти до GetMessage.
Фундаментальная ошибка.
Нельзя полагаться на «может успеть». Потому что может и не успеть. Это чревато ошибками синхронизации, взаимных блокировок и прочих гонок.
Цитата Сообщение от s2020mple Посмотреть сообщение
А как можно добиться, чтобы основной поток не зависал на GetMessage и при этом дальше создавались новые потоки?
Создавайте (или запускайте) дополнительные потоки в обработчике сообщения WM_CREATE. В этот момент окно уже создано, и оно может поймать все сообщения, которые отправлены ему из других потоков.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
25.02.2022, 20:39
Цитата Сообщение от Замабувараев Посмотреть сообщение
Создавайте (или запускайте) дополнительные потоки в обработчике сообщения WM_CREATE. В этот момент окно уже создано
У ТС нет никакого окна, и никто не пришлет ему WM_CREATE.

Цитата Сообщение от Замабувараев Посмотреть сообщение
Нельзя полагаться на «может успеть». Потому что может и не успеть
Согласен. Все бы нормально работало, если бы очередь сообщений создалась сама по себе, но она, оказывается, создастся только при первом вызове GetMessage. Можно сначала вызвать PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE), чтобы создать очередь сообщений, затем запустить потоки, после чего начать цикл обработки сообщений.
1
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
08.03.2022, 15:25
Цитата Сообщение от nonedark2008 Посмотреть сообщение
У ТС нет никакого окна, и никто не пришлет ему WM_CREATE.
Если нет окна, то зачем вообще отправлять оконные сообщения? Для этого эффективнее использовать события.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.03.2022, 15:25
Помогаю со студенческими работами здесь

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

Обмен сообщениями между формами
Проблема такая: есть одно окно , на нём кнопка &quot;ввести данные&quot; , при нажатии открывается другое окно, там мы вводим данные и закрываем...

Обмен сообщениями между сокетами
Есть два приложение одно - клиент, второе - сервер. using System; using System.Text; using System.Net; using System.Net.Sockets;...

Обмен сообщениями между приложениями
Здравствуйте. Хочу создать на C# приложение-клиент (графический интерфейс) и приложение-сервер (консоль) для обмена сообщениями между...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru