Jump to content

    

Borland C++. Как запустить программу в несколько потоков.

Собственно вопрос в теме.

 

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

 

Так вот если кнопкой читать какой либо большой файл или общатся по COM порту, то прога на длительные времена просто "подвисает" и перестает реагировать.

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

 

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

 

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

 

PS: среда C++Bulder 6.

Share this post


Link to post
Share on other sites

RSDN.ru: Работа с потоками в C# :rolleyes:

 

--

 

Эээээ... стоп! Какой еще WindowsForm в BCB++ 6?! :07: Окрывайте Google, спрашивайте "потоки с++", читайте..

Edited by SysRq

Share this post


Link to post
Share on other sites

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

Application->ProcessMessages()

тогда прога будет реагировать на другие события.

Share this post


Link to post
Share on other sites

Про потоки в билдере: смотри в хелпе класс TThread.

Share this post


Link to post
Share on other sites

Всем спасибо за ответы.

 

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

Application->ProcessMessages()

тогда прога будет реагировать на другие события.

 

Отлично, прямо то что надо в данной ситуации. На все реагирует, только не хочет закрывать прогу почемуто.

Share this post


Link to post
Share on other sites

Вот еще глюки поймал.

Почему то в билдере, при добавлении(создании) класса TThread, из ClassExplorer исчезли созданные мною ранее классы. Причем они все равно используются и проект компилируется, но ClassExplorer их не видит.

 

Что это может быть такое?

Share this post


Link to post
Share on other sites

Вот статья на русском для начала, потоки и синхронизация процесов, а там дальше разберётесь я думаю... хелп от билдера посмотрите...

rus5_Processes_and_Threads.pdf

Share this post


Link to post
Share on other sites
Всем спасибо за ответы.

Отлично, прямо то что надо в данной ситуации. На все реагирует, только не хочет закрывать прогу почемуто.

 

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

Share this post


Link to post
Share on other sites

Angelo, спасибо за PDF-ку, очень доходчиво написано.

 

Возник такой вопрос:

Я создаю объект TThread, и в Execute() ему помещаю то, что должно делатся в во втором потоке.

Из этого Execute я могу посылать сообщения(Postmessage) основному окну и сообщать о текущем состоянии и пр.

 

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

 

Что в этом случае делать? Просто объявить глобальную переменную

bool FLAG, в основном потоке писать в нее, а в дочернем постоянно читать?

Да, и как быть с ситуацией, когда запись FLAG прерывается на пол пути для переключения к другому процессу?

Использовать эмбедерские свойства volatile, или организовывать Mutex для этого флага?

Share this post


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

Не совсем понятно, причём тут окно...

Если текстовые сообщения - имхо, очереди как раз для этого придумали.

Или что имеется в виду?

Share this post


Link to post
Share on other sites

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.

 

Из этого я сделал вывод, что сообщения можно посылать только окнам.

Share this post


Link to post
Share on other sites
Возник такой вопрос:

...

Что в этом случае делать? Просто объявить глобальную переменную

bool FLAG, в основном потоке писать в нее, а в дочернем постоянно читать?

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

Использовать эмбедерские свойства volatile,

Не достаточно.

или организовывать Mutex для этого флага?

Да.

Share this post


Link to post
Share on other sites

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

 

HWND hWnd //handle of destination window

 

Тоесть только окнам.

Share this post


Link to post
Share on other sites
Да, и как быть с ситуацией, когда запись FLAG прерывается на пол пути для переключения к другому процессу?

Можно использовать функции Win API Interlocked... По-моему в Help'e описание присутствует.

Share this post


Link to post
Share on other sites
Можно использовать функции Win API Interlocked... По-моему в Help'e описание присутствует.

Можно. До тех пор пока sizeof(FLAG) <= 4

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this