Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программа выполняет длительный процесс, и находится в статусе "не отвечает" 
:(
    Опции темы
Нитонисе
Дата 24.9.2012, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(artsb @  24.9.2012,  10:49 Найти цитируемый пост)
А, вообще, это нужно было заранее продумывать. Тогда и переделывать ничего бы не пришлось.

Вот это точно smile 
PM MAIL   Вверх
Нитонисе
Дата 26.9.2012, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Переработал код, чтобы все вычисление шло в отдельном потоке, но что-то не работает.
В основной программе есть функция Calculate(), кторая выполняет расчет. Сначала она проверяет исходные данные и наполняет структуру с данными, необходимыми для расчета. Затем запускает отдельный поток, где сам расчет и происходит.
Код

void __fastcall TForm1::Calculate()
{
  //проверка корректности исходных данных, работаем с vcl
  //...

  // заполняем структуру
  TMyStruct S;
  S.a = 1;
  S.b = 2;
  S.c = 3;

  // запускаем отдельный поток
  TMyThread *Thr = new TMyThread(false,&S);

}

Вот так принципиально выглядит класс TMyThread
Код

class TMyThread : public TThread
{
  public:
    __fastcall TMyThread(bool CreateSuspended, TMyStruct *s) : TThread(CreateSuspended) {FreeOnTerminate = true; S = s;}
    void __fastcall Execute();
  private:
    TMyStruct *S;
}
void __fastcall TMyThread::Execute()
{
  int res = S->a + S->b + S->c; 
}
 
Проблема в том, что в поток структура S передается без данных. То есть вычислить res невозможно. Но как так? Ведь я же передал адрес нужной структуры данных из основного потока.
PM MAIL   Вверх
xvr
Дата 26.9.2012, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(Нитонисе @  26.9.2012,  10:51 Найти цитируемый пост)
Проблема в том, что в поток структура S передается без данных. То есть вычислить res невозможно. Но как так? Ведь я же передал адрес нужной структуры данных из основного потока. 

Вам нужно скопировать к себе структуру при старте Thread'а, т.к. ваша оригинальная структура выходит из области видимости и разрушается сразу после запуска thread'а

PM MAIL   Вверх
Нитонисе
Дата 26.9.2012, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(xvr @  26.9.2012,  11:02 Найти цитируемый пост)
Вам нужно скопировать к себе структуру при старте Thread'а, т.к. ваша оригинальная структура выходит из области видимости и разрушается сразу после запуска thread'а

Так ведь я в потоке работаю не с самой структурой, а с ее адресом. Этот адрес я и передаю при создании потока. Ведь эта операция корректна?
PM MAIL   Вверх
Dem_max
Дата 26.9.2012, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 14
Всего: 39



Ты вышел за пределы Calculate() и все твой объект TMyStruct S разрушен, а поток TMyThread(false,&S); запускается уже после выхода из Calculate() как ты думаешь какой адрес получит поток ???


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
xvr
Дата 26.9.2012, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(Нитонисе @  26.9.2012,  13:22 Найти цитируемый пост)
Ведь эта операция корректна?

Передача адреса корректна, а вот обращение по нему - нет. Dem_max вполне наглядно все расписал  smile 

PM MAIL   Вверх
Нитонисе
Дата 26.9.2012, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(Dem_max @  26.9.2012,  14:38 Найти цитируемый пост)
Ты вышел за пределы Calculate() и все твой объект TMyStruct S разрушен, а поток TMyThread(false,&S); запускается уже после выхода из Calculate() как ты думаешь какой адрес получит поток ???

Значит TMyStruct должна быть глобальной переменной? Ну или хотябы членом класса формы.
PM MAIL   Вверх
DarkProg
Дата 26.9.2012, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: нет
Всего: 19



Цитата(Нитонисе @  26.9.2012,  17:56 Найти цитируемый пост)
Значит TMyStruct должна быть глобальной переменной? Ну или хотябы членом класса формы. 

Нет, ты в поток должен отдать значения из этой структуры, либо сделать указатель на структуру, выделить под указатель память, и потом передать этот указатель, только выделенную память потом надо будет как-то освободить(либо в деструкторе, либо в конце вычислений).


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
Нитонисе
Дата 26.9.2012, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(DarkProg @  26.9.2012,  17:33 Найти цитируемый пост)
либо сделать указатель на структуру, выделить под указатель память, и потом передать этот указатель

Ну я это и имел ввиду. Объявить глобальную переменную - указатель на структуру, в функции Calculate() выделить память для TMyStruct, заполнить структуру данными, передать указатель классу TMyThread и там использовать эти данные в вычислениях. А освободить память видимо надо в деструкторе TMyThread? Насколько это будет корректно при завершении работы потока штатно (то есть когда вычисления закончены) или внештатно (пользователь нажал кнопку "Отмена", прервав расчет)?
PM MAIL   Вверх
DarkProg
Дата 26.9.2012, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: нет
Всего: 19



Цитата(Нитонисе @  26.9.2012,  18:52 Найти цитируемый пост)
Ну я это и имел ввиду. Объявить глобальную переменную - указатель на структуру

Да не нужна вам глобальная переменная! Указатель тем и хорош, что указатель вы отдадите потоку, и поток с ним сможет работать. И ничего ему не будет. В нынешнем варианте у вас объявляется переменная, которая "умирает" как только заканчивается выполнение процедуры, ну и собсно результат известен, а нужен указатель. Т.е. по сути сейчас компилятор выделяет память и освобождает её, и ему невдомёк, что адрес переданный в поток трогать нельзя. Используя указатель типа указатель на структуру вы уже сами начинаете управлять памятью, выделяя её, а переменная-указатель всего лишь является хранилищем для адреса и её разрушение после выхода из процедуры не будет иметь никакого значения для памяти которая выделена под структуру и значений которые там хранятся.

И не путайте глобальную переменную и локальную переменную.

Цитата(Нитонисе @  26.9.2012,  18:52 Найти цитируемый пост)
А освободить память видимо надо в деструкторе TMyThread?

Как реализуете, можно в деструкторе, можно в конце метода Execute, главное не забыть это сделать. Правильнее будет в деструкторе наверное в данном случае, особенно учитывая возможность прерывания вычислений.


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
xvr
Дата 26.9.2012, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Сделайте просто локальную копию. Вот так -
Код

class TMyThread : public TThread
{
  public:
    __fastcall TMyThread(bool CreateSuspended, TMyStruct *s) : TThread(CreateSuspended) {FreeOnTerminate = true; S = *s;}
    void __fastcall Execute();
  private:
    TMyStruct S;
}
void __fastcall TMyThread::Execute()
{
  int res = S.a + S.b + S.c; 
}


PM MAIL   Вверх
artsb
Дата 26.9.2012, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(xvr @  26.9.2012,  19:01 Найти цитируемый пост)
Сделайте просто локальную копию.

Тогда нужно не забыть перегрузить оператор присваивания. А то всплывёт потом "что-нибудь"...


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
xvr
Дата 26.9.2012, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(artsb @  26.9.2012,  20:33 Найти цитируемый пост)
Тогда нужно не забыть перегрузить оператор присваивания. А то всплывёт потом "что-нибудь"...

Ну если в TMyStruct кроме интов входит еще что-нибудь (например AnsiString), то это "что-нибудь" всплывет сразу  smile Свой оператор присваивания в таком случае явно не будет лишним  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.