Gambolt |
Отправлено: 03.05.2005, 17:17 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
Имеем:
QUOTE |
SERVICE.H
class TMainServ : public TService
{
__published: // IDE-managed Components
TServerSocket *CheckServ;
void __fastcall CheckServGetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread);
void __fastcall ServiceStart(TService *Sender, bool &Started);
void __fastcall ServiceStop(TService *Sender, bool &Stopped);
void __fastcall ServicePause(TService *Sender, bool &Paused);
void __fastcall ServiceContinue(TService *Sender, bool &Continued);
private: // User declarations
public: // User declarations
__fastcall TMainServ(TComponent* Owner);
TServiceController __fastcall GetServiceController(void);
friend void __stdcall ServiceController(unsigned CtrlCode);
void __fastcall LogP(AnsiString S);
};
extern PACKAGE TMainServ *MainServ;
class PACKAGE TMyServerThread : public Scktcomp::TServerClientThread
{
public:
__fastcall TMyServerThread(bool CreateSuspended, TServerClientWinSocket* ASocket)
: Scktcomp::TServerClientThread(CreateSuspended, ASocket)
{ CreateSuspended = false; KeepInCache=true; FreeOnTerminate=false; };
void __fastcall ClientExecute(void);
};
|
Еще имеем:
QUOTE |
void __fastcall TMyServerThread::ClientExecute(void)
{
while (!Terminated && ClientSocket->Connected)
{
try
{
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket, CLIENTWAITTIME);
try
{
char buffer[BUFFERSIZE];
memset( buffer, 0, sizeof(buffer) );
if (pStream->WaitForData(CLIENTWAITTIME))
{
if (pStream->Read(buffer, sizeof(buffer)) == 0)
{
ClientSocket->Close();
}
else
{
// Тест — возвращаем полученное...
pStream->Write( buffer, sizeof(buffer));
}
}
else
ClientSocket->Close();
}
__finally
{
delete pStream;
}
}
catch (...)
{
HandleException();
}
}
}
void __fastcall TMainServ::CheckServGetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
SocketThread = new TMyServerThread(false, ClientSocket);
}
|
Суть:
Соединений на серверный сокет может быть по самое нехочу. А прии создании следующего потока я утрачиваю доступ к предыдущему. Вопрос: Как поэлегантнее запхать их в динамический массив?
Типа привинтить к этому делу указатели на предыдущий (PrivThread) и последующий (NextThread) потоки? Если PrivThread==NULL то мы стоим на первом потоке, если NextThread==NULL на последнем. А снаружи болтается какие-нибудь FirstThread, LastTread для быстрого перемещения в верх и вниз массива и CurrThread для работы с выбранным потоком.
Идея в следующем:
Ставим указатель CurrThread на FirstThread, проверяем идентификатор потока (например ThreadId) если результат проверки не удовлетворителен, Сдвигаем указатель CurrThread на CurrThread->NextThread и так до получения удовлетворительного результата проверки (в этом случае просто работаем с выбранным потоком) или до CurrThread==LastThread (ну далее можно что нибудь тоже сделать)
Вот. Кто может что посоветовать?
|
|
Asher |
Отправлено: 04.05.2005, 08:31 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Привет.
Простой список указателей на ваши треды.
sdt::list
В этой постановке задачи непонятно кто отвечает за проверку жизнеспособности потоков.
Обычным решением считается создание набора постоянно существующих, спящих по SleepEx(INFINITE, TRUE); потоков в которые добавляются задания через QueueUserAPC. И увеличиваете счетчик заданий для того потока, котору добавили работу.
Только ваша добавляемая функция потока должна уметь уменьшать свой счетчик заданий.
Дальше ищите свободный, т.е. спящий и не потребляющий поток, и озадачиваете его. Если свободных нет, то или озадачиваете минимально нагруженного, или, если задержка недопустима, создаете новый поток и помещаете его в список sdt::list
Это уже от логики вашего приложения зависит.
|
|
Gambolt |
Отправлено: 04.05.2005, 08:38 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
Да нет тут тема в другом, потоки сами следят за своей жизнеспособностью. И как только функционал потока исчерпывается — завершаются, но при завершении поток должен уравнять указатель NextThread предыдущего потока со своим NextThread и PrevThread последующего со своим PrevThread после чего затерминейтиться. Признаком жизни потока является существование соединения по соответствующему сокету. |
|
Asher |
Отправлено: 04.05.2005, 09:26 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Тогда просто пусть поток делает remove своего элемента из доступного всем потокам списка.
Т.е. создали поток, указатель на него в список push(), у потока доступ к списку и знает указатель на себя.
Перед завершением ищет себя в списке и делает указателю remove.
Все.
|
|
|