Все вопросы связанные с программированием. Языки программирования. Средства разработки.
Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Опять Thread

Сообщение Borr »

Если мое приложение запускает кучу потоков, как мне можно их всех остановить при закрытии приложения.
Можно ли как то узнать какие потоки запускались моим приложением. Или как-то регистрировать потоки. Сейчас в главном модули программы объявляю все потоки а по том при закрытии проверяю их на Null и делаю им Terminate, но это не выход.
Стой там, иди сюда

Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Сообщение Borr »

Или описывать все Thred в пределах одного Юнита(ChildForm в MDI приложении) а потм просто при закрытии главной формы делать

Код: Выделить всё

  for(int i=0; i < Application->MainForm->MDIChildCount; i++)
    Application->MainForm->MDIChildren[i]->Close();
 Application->ProcessMessages();  
 if(Application->MainForm->MDIChildCount  != 0)
   {  
      Sleep(1000);
      this->Close();//Снова пробуем закрыть
    }
     //Повтряем эту функцию
Суть вся в том - не давать дочерней форме закрыться пока поток который она запустила не завершится по Terminate
А в главной форме проверять если все дочерние закрыты значит можно выгружать и главный поток(форму)
Стой там, иди сюда

Аватара пользователя
tAZAR
Не в сети
Модератор
Модератор
Сообщения: 567
Зарегистрирован: Ср июн 23, 2004 8:13
Откуда: г.Шахты

Сообщение tAZAR »

Я не знаю, поможет ли тебе это, но вот, за пять минут набросал. Разбирался на ходу, поэтому, может, я тебя не понял...

Код: Выделить всё

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
  void Cool();
class MyThread: public TThread
{
 public:
 bool IsAlive()
 {
  return !Terminated;
 }
 __fastcall MyThread(bool CreateSuspended):TThread(CreateSuspended)
 {
// Priority = tpLower;
 }

 void __fastcall Execute()
 {
      for(int i=0; i< 20; i++)
               MessageBoxA(NULL,"1","1",0);
      Terminate();
 }

};
//---------------------------------------------------------------------------
void Cool()
{
 MessageBoxA(NULL,"Terminated","Terminated",0);
}

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   MyThread *mt = new MyThread(false);
   while(mt->IsAlive())
   {
   }
   Cool();

}

//---------------------------------------------------------------------------


Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Сообщение Borr »

tAZAR, интересно конечно но немного не то, помоему это мне сколько потоков столько этих классов создавать т.е.

Код: Выделить всё

MyThread *mt = new MyThread(false); 
Если я сделал это несколько раз? (массив не подходит ).

У меня каждая форма будет запускать несколько разных потоков (с разной функциональностью). В этом аспекте мое решение пока мне кажется более симпатично. Т.Е привязать поток к его родной форме и не закрывать ее (форму) пока поток не сделает Terminate а с главной формы проверять все ли дочерние формы закрылись. По моему так.
Стой там, иди сюда

Аватара пользователя
Hank
Не в сети
Почётный форумщик
Почётный форумщик
Сообщения: 4299
Зарегистрирован: Чт май 05, 2005 19:35
Откуда: RnD

Сообщение Hank »

Borr,
(массив не подходит )
а список? )
В этом аспекте мое решение пока мне кажется более симпатично. Т.Е привязать поток к его родной форме и не закрывать ее (форму) пока поток не сделает Terminate а с главной формы проверять все ли дочерние формы закрылись.
как частный случай сгодиться, но строить всю логику на этом я бы не стал.
tAZAR,
while(mt->IsAlive())
{
}
ужосс ))

Код: Выделить всё

mt.WaitFor;
или уж, если хочется, чтобы форма не "подвисала"

Код: Выделить всё

while not mt.Terminated do
  Application.ProcessMessages;
Люблю повеселиться, особенно пожрать,
Люблю и поработать, особенно поспать )

Аватара пользователя
tAZAR
Не в сети
Модератор
Модератор
Сообщения: 567
Зарегистрирован: Ср июн 23, 2004 8:13
Откуда: г.Шахты

Сообщение tAZAR »

Eraser
mt.Terminated
В билдере это закрытая переменная класса (private) - поэтому я сделал функцию IsAlive

while(mt->IsAlive())
{
}
написано просто так, чтобы доказать, что IsAlive срабатывает. я не пытался написать здесь полное решение проблемы - я написал класс, и дал ему IsAlive только для того, чтобы можно было узнать, что поток цдох. Ее, соответственно, надо вызывать там, где хочется закрыть форму при уничтожении (завершении работы) потока.
Еще раз: код выше писал 5 минут, рассматривая по дороге документацию по билдеру...

А список, точнее, контейнер - это было б неплохо :-) Например - std::vector :-) Потребуется #include <vector.h>

Аватара пользователя
Hank
Не в сети
Почётный форумщик
Почётный форумщик
Сообщения: 4299
Зарегистрирован: Чт май 05, 2005 19:35
Откуда: RnD

Сообщение Hank »

tAZAR,
А список, точнее, контейнер - это было б неплохо
или TList :mrgreen:
Люблю повеселиться, особенно пожрать,
Люблю и поработать, особенно поспать )

Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Сообщение Borr »

или TList
Семен Семенович! в принципе и вектор бы сошел.
tAZAR ты пробовал на Bilder'овском компиляторе в вектор структуры или классы пихать? Я давно пробовал помоему были проблемы, или я был молодой...

А поток на работу можно проверять по Terminated (ето bool) посмотри я тут с Eraser'ом уже потоки мучал.
Стой там, иди сюда

Аватара пользователя
tAZAR
Не в сети
Модератор
Модератор
Сообщения: 567
Зарегистрирован: Ср июн 23, 2004 8:13
Откуда: г.Шахты

Сообщение tAZAR »

В общем, я решил проблему пока так, особо не напрягаясь:

Код: Выделить всё

//------------------------thread.cpp---------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "thread.h"
#include <map>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

using namespace std;

TForm1 *Form1;



void Cool();
class MyThread: public TThread
{
 public:
 int m_iID;
 bool IsAlive()
 {
  return !Terminated;
 }
 __fastcall MyThread(bool CreateSuspended, int iID):TThread(CreateSuspended)
 {
  m_iID = iID;
 }

 void __fastcall Execute()
 {
      HFILE hf;
      hf = _lopen("c:\\bigbyth.thr",OF_WRITE|OF_SHARE_EXCLUSIVE);
      for(int i=0; i< 200000; i++)
      {
       _lwrite(hf,"thread is working!!!\n",strlen("thread is working!!!\n"));
       Form1->Cool(true,m_iID);

      }
      _lclose(hf);
      hf = NULL;
      Form1->Cool(false,m_iID);
      Terminate();
 }

};
//---------------------------------------------------------------------------
void TForm1::Cool(bool isAlive,int iID)
{
     if(isAlive)
          Edit1->Text = "Working....";
     else
     {
          Edit1->Text = "Finished.";
          char buf[255];
          itoa(iID,buf,10);
          ListBox1->Items->Add(buf);
     }
}

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   //в этом месте все отлично работает с контейнерами:
   for(int i=0; i< 6; i++)
      thrs.insert(make_pair<int,MyThread*>(i,new MyThread(false,i)));
}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
     //А вот здесь не даем закрыться форме, если хотя бы один поток работает
     for(int i=0; i< thrs.size(); i++)
     {
             if(thrs[i] != NULL)
                   if(thrs[i]->IsAlive())
                   {
                          CanClose = false;
                          break;
                   }
     }

}
//---------------------------------------------------------------------------

//-------------------------thread.h-------------------------------------------

#ifndef threadH
#define threadH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <map>

using namespace std;

class MyThread;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
        TEdit *Edit1;
        TListBox *ListBox1;
        void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
private:	// User declarations
        MyThread *mt;
        map<int,MyThread*> thrs;
public:		// User declarations
        __fastcall TForm1(TComponent* Owner);
        void Cool(bool,int);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Аватара пользователя
tAZAR
Не в сети
Модератор
Модератор
Сообщения: 567
Зарегистрирован: Ср июн 23, 2004 8:13
Откуда: г.Шахты

Сообщение tAZAR »

забыл вычистить память... :-) ну ничего - это не принципиально в данном случае.

Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Сообщение Borr »

Спасибо.
Стой там, иди сюда

Аватара пользователя
tAZAR
Не в сети
Модератор
Модератор
Сообщения: 567
Зарегистрирован: Ср июн 23, 2004 8:13
Откуда: г.Шахты

Сообщение tAZAR »

или TList Mr. Green
ИМХО, map быстрее, а vector - еще быстрее :-)

Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Сообщение Borr »

TList тоже неплохо трудится я им в StrinGrid'ах по 15-20 тыс записей упорядочивал очень даже неплохо.
Стой там, иди сюда

Аватара пользователя
tAZAR
Не в сети
Модератор
Модератор
Сообщения: 567
Зарегистрирован: Ср июн 23, 2004 8:13
Откуда: г.Шахты

Сообщение tAZAR »

Borr писал(а):StrinGrid'ах по 15-20 тыс записей
Мама дорогая!
Вот уж точно УЖОС!!!! Зачем тебе одновременно показывать 15-20 тыс.записей????

Аватара пользователя
Borr
Не в сети
Частый гость
Частый гость
Сообщения: 338
Зарегистрирован: Ср сен 15, 2004 17:14
Откуда: Шахты
Контактная информация:

Сообщение Borr »

Я знаю! А юзер сказал сделай, но я выкрутился организовал им фильтр (вроде удобно всегда под рукой) они сами с него начинают работать.

Разговор не об этом я TList имел ввиду - неплохая штука.
Стой там, иди сюда

Ответить