Если мое приложение запускает кучу потоков, как мне можно их всех остановить при закрытии приложения.
Можно ли как то узнать какие потоки запускались моим приложением. Или как-то регистрировать потоки. Сейчас в главном модули программы объявляю все потоки а по том при закрытии проверяю их на Null и делаю им Terminate, но это не выход.
- Borr
- Частый гость
- Сообщения: 338
- Зарегистрирован: Ср сен 15, 2004 17:14
- Откуда: Шахты
- Контактная информация:
Опять Thread
Стой там, иди сюда
- Borr
- Частый гость
- Сообщения: 338
- Зарегистрирован: Ср сен 15, 2004 17:14
- Откуда: Шахты
- Контактная информация:
Или описывать все Thred в пределах одного Юнита(ChildForm в MDI приложении) а потм просто при закрытии главной формы делать
Суть вся в том - не давать дочерней форме закрыться пока поток который она запустила не завершится по Terminate
А в главной форме проверять если все дочерние закрыты значит можно выгружать и главный поток(форму)
Код: Выделить всё
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();//Снова пробуем закрыть
}
//Повтряем эту функцию
А в главной форме проверять если все дочерние закрыты значит можно выгружать и главный поток(форму)
Стой там, иди сюда
Я не знаю, поможет ли тебе это, но вот, за пять минут набросал. Разбирался на ходу, поэтому, может, я тебя не понял...
Код: Выделить всё
//---------------------------------------------------------------------------
#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
- Откуда: Шахты
- Контактная информация:
tAZAR, интересно конечно но немного не то, помоему это мне сколько потоков столько этих классов создавать т.е.
Если я сделал это несколько раз? (массив не подходит ).
У меня каждая форма будет запускать несколько разных потоков (с разной функциональностью). В этом аспекте мое решение пока мне кажется более симпатично. Т.Е привязать поток к его родной форме и не закрывать ее (форму) пока поток не сделает Terminate а с главной формы проверять все ли дочерние формы закрылись. По моему так.
Код: Выделить всё
MyThread *mt = new MyThread(false);
У меня каждая форма будет запускать несколько разных потоков (с разной функциональностью). В этом аспекте мое решение пока мне кажется более симпатично. Т.Е привязать поток к его родной форме и не закрывать ее (форму) пока поток не сделает Terminate а с главной формы проверять все ли дочерние формы закрылись. По моему так.
Стой там, иди сюда
Borr,
tAZAR,
или уж, если хочется, чтобы форма не "подвисала"
а список? )(массив не подходит )
как частный случай сгодиться, но строить всю логику на этом я бы не стал.В этом аспекте мое решение пока мне кажется более симпатично. Т.Е привязать поток к его родной форме и не закрывать ее (форму) пока поток не сделает Terminate а с главной формы проверять все ли дочерние формы закрылись.
tAZAR,
ужосс ))while(mt->IsAlive())
{
}
Код: Выделить всё
mt.WaitFor;
Код: Выделить всё
while not mt.Terminated do
Application.ProcessMessages;
Люблю повеселиться, особенно пожрать,
Люблю и поработать, особенно поспать )
Люблю и поработать, особенно поспать )
В билдере это закрытая переменная класса (private) - поэтому я сделал функцию IsAliveEraser
mt.Terminated
while(mt->IsAlive())
{
}
написано просто так, чтобы доказать, что IsAlive срабатывает. я не пытался написать здесь полное решение проблемы - я написал класс, и дал ему IsAlive только для того, чтобы можно было узнать, что поток цдох. Ее, соответственно, надо вызывать там, где хочется закрыть форму при уничтожении (завершении работы) потока.
Еще раз: код выше писал 5 минут, рассматривая по дороге документацию по билдеру...
А список, точнее, контейнер - это было б неплохо Например - std::vector Потребуется #include <vector.h>
- Borr
- Частый гость
- Сообщения: 338
- Зарегистрирован: Ср сен 15, 2004 17:14
- Откуда: Шахты
- Контактная информация:
Семен Семенович! в принципе и вектор бы сошел.или TList
tAZAR ты пробовал на Bilder'овском компиляторе в вектор структуры или классы пихать? Я давно пробовал помоему были проблемы, или я был молодой...
А поток на работу можно проверять по Terminated (ето bool) посмотри я тут с Eraser'ом уже потоки мучал.
Стой там, иди сюда
В общем, я решил проблему пока так, особо не напрягаясь:
Код: Выделить всё
//------------------------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