информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяЗа кого нас держат?Все любят мед
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Перевод Firefox на DNS over HTTPS 
 Microsoft закрыла серьёзную уязвимость,... 
 Прощаемся с Windows 7 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
А через указатель тож никак? 10.11.03 15:36  Число просмотров: 997
Автор: CrazyPitbull Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Я о другом, когда программа работает, если я буду работать с интерфейсом, то когда я из процесса обращаюсь к одному из компонентов, вылетает исключение, это нужно делать через Sinhronise? если да, то как?
<programming>
[C++] Как запустить в программе паралельный поток обработки данных? 07.11.03 20:21   [Ktirf]
Автор: CrazyPitbull Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Проблема такая, программа обрабатывает данные и одновременно с обработкой должна быть возможность работы с интерфейсом... Как это сделать? Насколько я понимаю необходимо запустить новый поток для обработки данных, тогда программа висеть не будет? Пишу в Builder'e. Если можно посмотреть исходники какие или есть дока по данной теме буду очень благодарен. Заранее спасибо!
[C++] Поиск по форуму тоже рулит... 08.11.03 09:09  
Автор: HandleX <Александр Майборода> Статус: The Elderman
<"чистая" ссылка>
> Проблема такая, программа обрабатывает данные и
> одновременно с обработкой должна быть возможность работы с
> интерфейсом... Как это сделать? Насколько я понимаю
> необходимо запустить новый поток для обработки данных,
> тогда программа висеть не будет? Пишу в Builder'e. Если
> можно посмотреть исходники какие или есть дока по данной
> теме буду очень благодарен. Заранее спасибо!

Потоки дело сурьёзное...
Часто выгода от них призрачная...
Если нужно, чтобы интерфейс приложения не висел во время обработки данных, тебе может помочь Application->ProcessMessages().

Пример (на Delphi, но ты поймёшь, imho)
procedure TForm1.Button1Click(Sender: TObject);
begin
  If Button1.Tag <> 0 Then
  Begin
    Button1.Tag := 0;
    Exit;
  End;
  Button1.Caption := 'Stop';
  Repeat
    Button1.Tag := Button1.Tag + 10;
    Caption := IntToStr(Button1.Tag);
    Application.ProcessMessages;
    sleep(100);
  Until Button1.Tag = 0;

  Button1.Caption := 'Start';
  Caption := '0';
end;


Суть примера поясняю — эдакий старт-стоповый таймер на одной кнопке с циклом обработки без потоков ;-) Ключевой элемент, используемый для отсановки обработки - поле TButton.Tag. В принципе, можно завести глобальную переменную под это дело.

Смотри тута. Читай все ветки ;-)
не очень я люблю ProcessMessages 08.11.03 09:36  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
С ним всякие глюки иногда бывают не очень понятные и если его засунуть в неудачное место может получится его рекурсивный вызов самого себя. Я обычно делаю BeginThread (с CreateThread могут быть проблемы с работой с динасический памятю из разных потоков) затем ставлю оюработчик сообщений на какоенить окно и свойства VCL'ных объектов из потоков меняю вызовом SendMessage у которого wParam - код функции а lParam -указатель на структуру параметров. Затем обертываю весь обработчик в try..catch и если у юзера вылетел глюк то ему показывается что где и когда.
Ну как-бы гибкость тоже должна быть ;-) 08.11.03 09:50  
Автор: HandleX <Александр Майборода> Статус: The Elderman
<"чистая" ссылка>
> С ним всякие глюки иногда бывают не очень понятные и если
> его засунуть в неудачное место может получится его
> рекурсивный вызов самого себя. Я обычно делаю BeginThread
> (с CreateThread могут быть проблемы с работой с
> динасический памятю из разных потоков) затем ставлю
> оюработчик сообщений на какоенить окно и свойства VCL'ных
> объектов из потоков меняю вызовом SendMessage у которого
> wParam - код функции а lParam -указатель на структуру
> параметров. Затем обертываю весь обработчик в try..catch и
> если у юзера вылетел глюк то ему показывается что где и
> когда.
Я про простые случаи имел ввиду.
Пусть автор поста знает все возможные варианты...
В потоках тоже могут быть всякие трудновоспринимаемые глюки... Особенно если учесть, что TForms и прочие гуевые библиотеки плохо переносят многопоточность. С использованием TThread тоже достаточно гемора можно поймать.

Короче, всё это на любителя. Пусть автор поста станет гибче в своих решениях и знает про все фичи.
Ну так SendMessage как раз против глюков в потоках 08.11.03 09:57  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
> Я про простые случаи имел ввиду.
> Пусть автор поста знает все возможные варианты...
Ну да в принципе если ему просто построить график какой нибудь то ProcessMessages самое то
> В потоках тоже могут быть всякие трудновоспринимаемые
> глюки... Особенно если учесть, что TForms и прочие гуевые
> библиотеки плохо переносят многопоточность.
SendMessage посылает сообщение основному потоку и ждет завершения его обработки - и глюков никаких. Правда конечно не совсем красиво вызывать какуюто другую функцию которая к примеру добавляет TListItem через SendMessage зато не глючит
Ok. 08.11.03 10:08  
Автор: HandleX <Александр Майборода> Статус: The Elderman
<"чистая" ссылка>
[C++] Все таки RTFM рулит 08.11.03 00:53  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Проблема такая, программа обрабатывает данные и
> одновременно с обработкой должна быть возможность работы с
> интерфейсом... Как это сделать? Насколько я понимаю
Насколько я помню, как раз цикл GetMessage/DispatchMessage как раз и запускается отдельным тредом (по крайней мере так в MFC, в vcl скорее всего тоже), в основном (который WinMain) же можно делать что угодно. Если же действительно нужен новые тред, то нужно отнаследоваться от класс TThread (кажется так) и переопределить виртальную функцию Execute. Тогда по new TMyThread будет создаваться поток, исполняющий данную функцию, в деструкторе (delete) он будет уничтожаться.

Кроме того, как уже упоминалось советую CreateThread.

> можно посмотреть исходники какие или есть дока по данной
> теме буду очень благодарен. Заранее спасибо!
Дока - это билдеровский хелп.

ЗЫ: Насколько я понимаю, если возник вопрос по созданию потоков, следующий вопрос будет по их синхронизации. Сразу отвечу, что тема эта достаточно обширная и помочь может только тщательный RTFM
Основные виды синхронизации:
1) Разделяемая память: ну это понятно. Контекст памяти у разных потоков для одного процесса один, так что никаких дополнительных извращений не надо
2) Event-ы (события): CreateEvent и сопутствующие - за дополнительной инфой в MSDN
3) Mutex-ы (mutually exclusive - взаимно исключающие) CreateMutex и остальные, описание в MSDN
4) Semaphore-ы (семафоры) CreateSemaphore ...
5) Named Pipe-ы (именованные потоки) CreateNamedPipe (CreateFile тоже умеет их создавать) ...

Кроме того, если все таки воспользуешься TThread-ом советую посмотреть в описание его member-функций. Я его юзал давно (лет 5 назад), но что то такое там точно есть
[C++] Неплохо... но как переопределить Execute? 08.11.03 15:24  
Автор: CrazyPitbull Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Вроде наплохо с TThread'oм работать. Я отнаследовал создал свою функцию оюработки, но немогу переопределить Execute, нужно передать указатель на мою функцию или что?
[C++] Просто переопределить 08.11.03 16:49  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Вроде наплохо с TThread'oм работать. Я отнаследовал создал
> свою функцию оюработки, но немогу переопределить Execute,
> нужно передать указатель на мою функцию или что?
В vcl записано примерно следующее

class TThread {
//...
protected:
void Execute(аргументы);
};

void TThread::Execute(аргументы) {
// stub
}

Ты делаешь
class TMyThread {
protected:
virtual void Execute(аргументы);
};

void TMyThread::Execute(аргументы) {
// Здесь тело твоего потока (функция, которая будет исполняться в новом потоке)
}

Главное следи, чтобы типы аргументов совпадали, иначе ты не переопределишь, а перегрузишь (читай введешь еще одну функцию) функцию Execute.

А вообще почитай про работу с виртуальными функциями.
[C++] Так и сделал, но иногда глючит... 09.11.03 02:33  
Автор: CrazyPitbull Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Так и сделел, вроди работает, если не трогать окно программы, а если поработать с интерфейсом, то после завершения задачи выкидывает исключение...
А вот для работы с интерфейсом у TThread есть метод Synchronize 09.11.03 09:44  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
Который реализован через SendMessage. Нельзя из других потоков обращаться к VCL компонентам, будут именно такие глюки. В хелпе кстати об этом написано.
А через указатель тож никак? 09.11.03 12:24  
Автор: CrazyPitbull Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Вот какая досада, как раз нужно обращаться к одному из компанентов... Чтож делать? Мож обойти как можно или есть какий хитрый счпособ? Я пробовал в отнаследованном классе создавать указатель на компонент, а в конструкторе пихал в него адрес того к которому нужно обратиться, но опять вылетает исключение!
А через указатель тож никак? 09.11.03 13:05  
Автор: Killer{R} <Dmitry> Статус: Elderman
Отредактировано 09.11.03 13:18  Количество правок: 3
<"чистая" ссылка>
Во первых прежде чем закрывать свою прогу надо остановить поток. Во вторых я не очень понял что именно ты хочешь обходить хитрым способом и при чем тут указатель? Там вроде везде к VCL классам обращение через указатели делается. Просто если хочешь изменить например текст в каком нибудь EditBox'е то вызываешь в Synchronize процедуру которая его меняет и все.
А через указатель тож никак? 10.11.03 15:36  
Автор: CrazyPitbull Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Я о другом, когда программа работает, если я буду работать с интерфейсом, то когда я из процесса обращаюсь к одному из компонентов, вылетает исключение, это нужно делать через Sinhronise? если да, то как?
А хелпы читать гордость мешает? 10.11.03 17:45  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
Цитирую:
This example shows how to call a button’s click method in a thread-safe manner:

void __fastcall TMyThread::PushTheButton(void)

{
Button1->Click();
}

void __fastcall TMyThread::Execute()
{
...
Synchronize(PushTheButton);
...
}
А мона еще проще 08.11.03 17:37  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
File->New->Other->Thread Object хотя имхо BeginThread еще проще Ж)
[C++] Все таки RTFM рулит 08.11.03 02:16  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Кроме того, если все таки воспользуешься TThread-ом советую
> посмотреть в описание его member-функций. Я его юзал давно
> (лет 5 назад), но что то такое там точно есть

Совершенно точно. Сам я юзал тоже давно. Но вроде всё получалось в BCB++.

А в части примеров(квуик старт), см. в папке
C:\Program Files\Borland\CBuilder6\Examples\Apps\Threads

PS. Я б стал копать API, позже, когда бы увител что класса TThread от BCB++
уже недостаточно.
[C++] Ключевые слова - threads, multithreading 07.11.03 22:11  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
<"чистая" ссылка>
Можно также посмотреть документацию на WinAPIшный вызов CreateThread (и его близких родственников).
[C++] CreateThread - это оно и есть. 10.11.03 20:13  
Автор: vagrant Статус: Незарегистрированный пользователь
<"чистая" ссылка>
CreateThread - это оно и есть. У меня так работает счетная программа для моделирования полимеризации, сделанная из Buildera.
Могу для примера привести кусочек.

По кнопочке запускается обработчик
void __fastcall TRCDesk::btStartProcessClick(TObject *Sender)
{
if(Indicator==0)
{btStartProcess->Enabled=false; Indicator=1;
btKillProcess->Enabled=true; IndRotation=1;
//-----------------------------------------------------------------
RIVTr1=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ReactorIV_Thread,
(LPVOID)NULL, THREAD_SUSPEND_RESUME, &Tid);
lstEvent=CreateEvent(NULL,false,false,"lst"); lst=1; ltime_ind=0;
//-------------------------------------------------------------------
btLife->Enabled=true;
AttrX = GetSystemMetrics(SM_CXFULLSCREEN);
AttrY = GetSystemMetrics(SM_CYFULLSCREEN);
TrackBarX->Position=-alphaVolume;
TrackBarY->Position=-betaVolume;
TrackBarZ->Position=-gammaVolume;
sc=long(float(AttrY)/1.732/float(L.x));

};
}

котрый и запускает процесс ReactorIV_Thread

DWORD ReactorIV_Thread(LPVOID param);
DWORD Tid;
HANDLE RIVTr1; HANDLE lstEvent;

DWORD
ReactorIV_Thread(LPVOID param)
{
...здесь все вычисления
}

если надо убить процес, запускаем функцию TerminateThread(RIVTr1,NULL);

Работает все надежно, как лопата.
Весь интерфейс и визуализация - снаружи потока.
А в лопате есть потенциальный баг 11.11.03 01:42  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
CreateThread в билдере лучше не юзать а вместо него юзать BeginThread. И кстати что означает - "Весь интерфейс и визуализация - снаружи потока."?
1  |  2 >>  »  






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2020 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach