Jump to content

    
Sign in to follow this  
Amper25

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

Recommended Posts

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

 

Есть проект типа 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, из 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
Да, и как быть с ситуацией, когда запись FLAG прерывается на пол пути для переключения к другому процессу?

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this