|
|
Home » U++ Library support » U++ MT-multithreading and servers » How to close a Thread?
How to close a Thread? [message #38022] |
Wed, 28 November 2012 16:10 |
NilaT
Messages: 70 Registered: November 2011 Location: Austria
|
Member |
|
|
Hello,
I currently have a huge problem, hope you can help me.
I have a (Single<>)class which includes a Thread.
I need to use the thread from different positions of my main program.
The problem is, that I need to stop the thread before closing a dialog, but how can I do that? I searched on the site, in the forum, on google... But I found nothing usefull.
All I found was "ShutdownThreads", but this only sets a flag and does not stop the thread itself...
I also tried to Close the Handle after GetHandle(), with no success.
If you need some code, look here:
void TCPConnection::startChecking()
{
// Thread starten
if(s.IsOpen()) // s is a Socket Connection
{
m_terminateThread = false;
t.Run(THISBACK(cb));
}
}
void TCPConnection::stopChecking()
{
// thread beenden
if(t.IsOpen())
m_terminateThread = true;
}
void TCPConnection::cb()
{
while(!m_terminateThread)
{
tempBuffer = s.Read(1000);
if(!IsNull(tempBuffer))
{
buffer += tempBuffer;
tempBuffer.Clear();
WhenDataReceived();
}
}
// CloseHandle(t.GetHandle()); // wont work
bool TCPConnection::hasThreadStopped()
{
return !t.IsOpen();
}
And on the main program I do the following:
void xxxDlg::onCancel()
{
if(TcpConnection().s.IsOpen()) // TcpConnection() returns ref on Single<TCPConnection>
{
TcpConnection().stopChecking();
while(!TcpConnection().hasThreadStopped())
{
Sleep(50); // this is where I stuck... The thread is not closed!!!!!
}
TcpConnection().s.Close();
}
Break(IDCANCEL);
}
Thanks in advance
|
|
|
Re: How to close a Thread? [message #38024 is a reply to message #38022] |
Wed, 28 November 2012 17:05 |
|
Hi NilaT
The problem is that IsOpen() does something slightly different than you think Thread docs | bool IsOpen() const
Thread represents an existing thread. Note that the thread can be already finished and not running anymore (calling to Wait in that case returns immediately).
| I.e. it returns false only before the thread is started and true always after it started, regardless of the current state. Other threads have no idea about what happens elsewhere.
The only reliable way to end a thread is to finish it from within. If you want to stop all running threads, just call ShutdownThreads() and make sure that all threads (well, except the main one, ussually) check periodically state of IsShutdownThreads(). If you need to stop only one particular thread, you must create your own flag that you can set in main thread to signalize the other one to finish itself. If necessary, the thread can also report that it is closing in similar way.
Best regards,
Honza
|
|
|
|
Re: How to close a Thread? [message #38041 is a reply to message #38032] |
Thu, 29 November 2012 07:28 |
|
NilaT wrote on Wed, 28 November 2012 20:54 | When I call ShutdownThreads() within a class, will only the local threads be closed? (which are in the same scope)
Because I have more threads in my main program, which should NOT shutdown.
| ShutdownThreads is a global flag, so it shutsdown everything. Also, it is not reusable, once you set it, there is currently no way to reset.
NilaT wrote on Wed, 28 November 2012 20:54 | And even if all Threads get the Shutdown flag set, they won't stop if I do not check the shutdown flag with IsShutdownThreads, right?
| Yes, you have to explicitly check it.
NilaT wrote on Wed, 28 November 2012 20:54 | What do you mean with "create my own flag"?
Well, I think I have to study the source of ShutdownThreads, maybe I understand then...
| By flag I mean just any variable shared between the threads. Below is an example very loosely based on your code. I just stripped down all the specific parts and made it into a simple console application. It should be enough to send you in the right direction
#include <Core/Core.h>
using namespace Upp;
struct TCPConnection {
bool m_terminateThread;
bool m_isOpen;
typedef TCPConnection CLASSNAME;
TCPConnection(): m_terminateThread(false), m_isOpen(false) {}
void startChecking()
{
LOG("thread started");
if(!m_isOpen) //do not reopen if already opened
{
m_terminateThread = false;
m_isOpen = true;
Thread::Start(THISBACK(cb));
}
}
void stopChecking()
{
m_terminateThread = true;
LOG("thread told to stop");
}
void cb()
{
LOG("thread starting");
while(!m_terminateThread)
{
LOG("thread running");
Sleep(222); // do some "work"
}
LOG("thread closing");
m_isOpen = false;
}
bool hasThreadStopped()
{
LOG("thread checked");
return !m_isOpen;
}
};
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_CERR);
TCPConnection t;
t.startChecking();
Sleep(1000);
t.stopChecking();
while(!t.hasThreadStopped())
{
Sleep(50);
}
LOG("thread has stopped");
}
Honza
|
|
|
|
Goto Forum:
Current Time: Sat May 04 13:22:14 CEST 2024
Total time taken to generate the page: 0.01578 seconds
|
|
|