Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Borland C++. Как запустить программу в несколько потоков.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Amper25
Собственно вопрос в теме.

Есть проект типа WindowsForm, всякие кнопочки и прочая лабуда. Проблема в следующем, при нажатии на кнопку, управление к форме возвращается только после того, как завершится выполнение функции, привязаной к данной кнопке.

Так вот если кнопкой читать какой либо большой файл или общатся по COM порту, то прога на длительные времена просто "подвисает" и перестает реагировать.
Самое простое что мне пришло на ум - это организовать чтение или обмен в другом потоке(tread). Но как это сделать я не представляю. Вообще в проекте типа формы это реально?

В данный момент все решено с помощью объекта TIMER с периодом 1мс. Процесс чтения разбивается на куски, и после каждых 2кб данных, ждем следующее переполнение. Метод конечно крайне кривой, и хотелось бы сделать как нормальные люди...

Вообщем, объясните, если не трудно что и как надо делать, или хоть направление куда идти.

PS: среда C++Bulder 6.
SysRq
RSDN.ru: Работа с потоками в C# rolleyes.gif

--

Эээээ... стоп! Какой еще WindowsForm в BCB++ 6?! 07.gif Окрывайте Google, спрашивайте "потоки с++", читайте..
DeadMoroz
Еще, если по-простому без тредов, можно в длительном цикле написать
Application->ProcessMessages()
тогда прога будет реагировать на другие события.
o-henry
Про потоки в билдере: смотри в хелпе класс TThread.
Amper25
Всем спасибо за ответы.

Цитата
Еще, если по-простому без тредов, можно в длительном цикле написать
Application->ProcessMessages()
тогда прога будет реагировать на другие события.


Отлично, прямо то что надо в данной ситуации. На все реагирует, только не хочет закрывать прогу почемуто.
Amper25
Вот еще глюки поймал.
Почему то в билдере, при добавлении(создании) класса TThread, из ClassExplorer исчезли созданные мною ранее классы. Причем они все равно используются и проект компилируется, но ClassExplorer их не видит.

Что это может быть такое?
Angelo
Вот статья на русском для начала, потоки и синхронизация процесов, а там дальше разберётесь я думаю... хелп от билдера посмотрите...
Syberian
Цитата(Amper25 @ Sep 25 2008, 17:53) *
Всем спасибо за ответы.
Отлично, прямо то что надо в данной ситуации. На все реагирует, только не хочет закрывать прогу почемуто.


Чтобы оно закрыло прогу, надо выйти из процедуры. Terminate и проч. не катят. Единственный выход - вместе с ProcessMessages делать проверку глобальной переменной (типа if (CloseFlag) {Application->Terminate; return;}), а в эвенте формы OnClose устанавливать CloseFlag в 1
Amper25
Angelo, спасибо за PDF-ку, очень доходчиво написано.

Возник такой вопрос:
Я создаю объект TThread, и в Execute() ему помещаю то, что должно делатся в во втором потоке.
Из этого Execute я могу посылать сообщения(Postmessage) основному окну и сообщать о текущем состоянии и пр.

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

Что в этом случае делать? Просто объявить глобальную переменную
bool FLAG, в основном потоке писать в нее, а в дочернем постоянно читать?
Да, и как быть с ситуацией, когда запись FLAG прерывается на пол пути для переключения к другому процессу?
Использовать эмбедерские свойства volatile, или организовывать Mutex для этого флага?
MrYuran
Цитата(Amper25 @ Sep 29 2008, 16:12) *
Но из основного окна я не могу посылать сообщения дочернему потоку, так как объект TThread не является окном.

Не совсем понятно, причём тут окно...
Если текстовые сообщения - имхо, очереди как раз для этого придумали.
Или что имеется в виду?
Amper25
BOOL PostMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);


Проблема в этом:
HWND hWnd, // handle of destination window

Если я в качестве этого поставлю:
MY_Thread->Handle,
то компилятор ругается:

Error: Cannot convert "const unsigned int" to "void"

Потому что FORM->Handle - имеет тип void*
а TThread->Handle это просто константа типа unsigned int.

Из этого я сделал вывод, что сообщения можно посылать только окнам.
vik0
Цитата(Amper25 @ Sep 29 2008, 15:12) *
Возник такой вопрос:
...
Что в этом случае делать? Просто объявить глобальную переменную
bool FLAG, в основном потоке писать в нее, а в дочернем постоянно читать?

Типа того. Только лучше не глобальную, а внутри Вашего класса-потока. И обернуть доступ к ней фунциями, обеспечивающими атомарность доступа.
Цитата
Использовать эмбедерские свойства volatile,

Не достаточно.
Цитата
или организовывать Mutex для этого флага?

Да.
Amper25
да и в самом определении PostMessage

HWND hWnd //handle of destination window

Тоесть только окнам.
Asb
Цитата(Amper25 @ Sep 29 2008, 16:12) *
Да, и как быть с ситуацией, когда запись FLAG прерывается на пол пути для переключения к другому процессу?

Можно использовать функции Win API Interlocked... По-моему в Help'e описание присутствует.
vik0
Цитата(Asb @ Sep 29 2008, 16:18) *
Можно использовать функции Win API Interlocked... По-моему в Help'e описание присутствует.

Можно. До тех пор пока sizeof(FLAG) <= 4
XVR
Цитата(Amper25 @ Sep 29 2008, 16:35) *
BOOL PostMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);

Проблема в этом:
HWND hWnd, // handle of destination window

Из этого я сделал вывод, что сообщения можно посылать только окнам.
Можно и не только окнам (см. PostThreadMessage) Но учти, что бы это сообщение дошло по назначению thread, которому оно посылается, должен крутить цикл обработки сообщений (GetMessage/DispatchMessage), возникает вопрос - нафига тогда нужен такой thread?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.