Click here to Skip to main content
15,889,724 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Scenario:

1.)Have a boolean array of length 4.
2.)I have a thread that is created in function 1 to execute function 3
3.)I have a function 2 that deletes the boolean array

how do i stop any existing threads from executing function3 if boolean array is deleted?

C++
public:
function 1
function 2
function 3
bool bArray[4];
Handle mainHandle;


function1()//called for every one second until DestroyTimer() is called
{
mainHandle = CreateThread(NULL, 0, ::function3, this, 0, NULL);
}

function3()
{
bArray[2] = false;
}

function2()
{
DestroyTimer();
bArray = NULL;
//here comes the problem, event though i called destroy timer there are threads that are already created and when they execute function3 they throw an assertion that bArray is NULL.
}


So to solve this. Before deleting bArray i want to terminate or suspend any existing threads, i have the Handle to the thread. how do i suspend or stop the thread from executing?
Posted
Updated 5-Nov-12 4:16am
v2
Comments
pasztorpisti 5-Nov-12 12:21pm    
It can easily happen that using multiple threads in your code isn't reasonable however we can not tell this from what you have shared with us. You might be defeating the whole purpose of threading and using threads just to overcomplicate your case. If you insist on using more threads then check out what data is accessed by more than one thread and if at least one of the threads performs write (and not only read) then you have to use a synchronization primitive associated with that data and you have to hold the lock on every thread while performing the read or write.
In your case on windows using a CRITICAL_SECTION could do the job. in function3() you should call EnterCriticalSection() before assigning values into the array and you should also check wheter its already null or not. Then you LeaveCriticalSection() after performing the assignment. Similarly you should use EnterCriticalSection() and LeaveCriticalSection() before and after bArray=NULL. At program startup you should initialize the criticalsection object once with InitializeCriticalSection() and then destory it with Destroy it with DeleteCriticalSection() when cleaning up.
mbue 5-Nov-12 12:44pm    
What about waiting until thread is ready?
WaitForSingleObject(mainHandle,INFINITE)
amarasat 5-Nov-12 14:37pm    
Is this a solution:

public:
function 1
function 2
function 3
bool arrayDeleted = false;
bool bArray[4];
Handle mainHandle;


function1()//called for every one second until DestroyTimer() is called
{
if(!arrayDeleted)
mainHandle = CreateThread(NULL, 0, ::function3, this, 0, NULL);
}

function3()
{
if(!arrayDeleted)
bArray[2] = false;
}

function2()
{
DestroyTimer();
arrayDeleted = true;
DWORD status = WaitForSingleObject(mainHandle,INFINITE);
if (status == WAIT_OBJECT_0)
{
bArray = NULL;
}
//here comes the problem, event though i called destroy timer there are threads that are already created and when they execute function3 they throw an assertion that bArray is NULL.
}

If you want to prevent function3 to be executed with some invalid data, then you probably have to mark your data as invalid in some way, and to check inside function3 for validity. Or do it in function1 before starting thread. I don't understand what you would like to do, but I think you need to use standard synchronization objects.
 
Share this answer
 
Typically, one uses a mechanism to signal to each thread when it should stop executing, for example by a bool variable that the thread regularly checks or some more refined way using the standard synchronization tools. That usually involves checking regularly inside your thread whether your creator wants you to terminate.

Once you have such a mechanism in place, you simply set the signal for all of your threads, wait until they have terminated, and then you can start destroying things that are being accessed by your threads.
 
Share this answer
 
Comments
amarasat 5-Nov-12 14:32pm    
This is what i was looking for:
""you simply set the signal for all of your threads, wait until they have terminated"": How do i achieve this, are you saying about "WaitForSingleObject(mainHandle,INFINITE)" and when it returns WAIT_OBJECT_0 then avoid creating new threads and destroy the array. or is there someother way?

Is this a solution:
public:
function 1
function 2
function 3
bool arrayDeleted = false;
bool bArray[4];
Handle mainHandle;

function1()//called for every one second until DestroyTimer() is called
{
if(!arrayDeleted)
mainHandle = CreateThread(NULL, 0, ::function3, this, 0, NULL);
}

function3()
{
if(!arrayDeleted)
bArray[2] = false;
}

function2()
{
DestroyTimer();
arrayDeleted = true;
DWORD status = WaitForSingleObject(mainHandle,INFINITE);
if (status == WAIT_OBJECT_0)
{
bArray = NULL;
}
//here comes the problem, event though i called destroy timer there are threads that are already created and when they execute function3 they throw an assertion that bArray is NULL.
}
nv3 5-Nov-12 18:05pm    
In the simplest scenario you can use a simple global bool variable that you set in your main program. Your threads should look regularly at this bool and continue working as long as it set to true, otherwise terminate.

Now, in your main program you set this bool to true before starting the threads. Then, when you want to do the cleanup, set the bool to false and wait until all threads have terminated. This last part is a bit tricky. You can wait in main for a thread termination by way of doing a WaitForSingle (or Multiple) Object on the thread handle.

Once your threads have all terminated, you are good to do the cleanup.
I think your concept is either plain wrong or really unusual, or you did not explain it very well.

You normally do not create a thread that runs one line of code and exits.

The thread function normally would look like:

function3()
{
  while (!bExitThread)
  {
      doSomething();
  }
};


You could modify this a bit:

function3()
{
  while (!bExitThread)
  {
      if (!bSuspended)
      {
          doSomething();
      }
      else
      {
          Sleep(100); // avoid busy waiting
      }
  }
}


Now you can:
1) Make thread exit cleanly by setting bExitThread to TRUE
2) Make thread "suspended" by setting bSuspended to TRUE without destroying the underlying OS thread (and you can resume it again by setting bSuspended to FALSE)
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900