Jump to content
  • Advertisement
Sign in to follow this  
mateo

Restarting threads

This topic is 4531 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was wondering if it is possible to restart a thread after it finishes. I was using "SendMessage, windowhandle, WM_USER", right after the thread finished, then returned, which would allow the main process to handle the WM_USER message sent to the thread. Here is where I get stuck, The message gets sent just fine, but I need a way to restart the thread. Hopefully without destroying and then recreating the thread. Any suggestions?

Share this post


Link to post
Share on other sites
Advertisement
I'm not entirely sure what you are wanting to do, but rather than end a thread, you should set it in an idle state so when you need to restart it, it just changes states, so you do not have to destroy/recreate it. For an example using goto:

int myThread()
{
static int state = 0;
int var1 = 4;
int done = false;
...
Start:
if(state == 0)
{
while(!done)
{
}
state = 1;
}
while(state == 1)
{
if(GetMessage(WM_USER, ...))
state = 2;
else
sleep();
}
if(state == 2)
{
// reset variables here
state = 0;
goto Start;
}
return 0;
}

Now I know there are probabally other ways that do not involve using goto, but that's an example of something that should ideally work, well the concept. When you wanted to quit the thread, the state would just be set to a number other than 0, 1, and 2, and it will fall though.

Share this post


Link to post
Share on other sites
Thanks for your help Drew. I'd like to be able to do it without the endless loop, 'Sleep' stalls my example too much. Here is a little example of what I want to do:

WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
......
case WM_USER:
Here is where I get stuck, I want to restart the thread here
but haven't figured out a way to do it properly yet.
.....
}

MyThread()
{
.... Draw a random rectangle in the client area of a window

// The thread is finished so send a message to the message handler
SendMessage, [windowhandle], WM_USER, 0, 0,
return 0
}

Share this post


Link to post
Share on other sites
There is no way to restart a thread once it runs out of its work function. Every handle you've got left needs to be released with the CloseHandle function.

You have a potential problem in your code: You're using SendMessage, which usually waits for the answer. In your case the other thread gets the WM_USER message while the thread is still alive!

The best way to "auto-restart" a thread would really be a sort of endless loop which checks for an event being set (Look into CreateEvent and WaitForSingleObject). Why bother the hassle with another thread to keep the current thread active?

Share this post


Link to post
Share on other sites
Sounds like a job for a semaphore....

Though doesn't GetMessage block anyway??? so why is sleep() even being called?

Sorry but that's the limit of my win32 knowledge.

Share this post


Link to post
Share on other sites
Something like this?


HANDLE hEvent;

DWORD MyThread()
{
for(;;)
{
DWORD ret = ::WaitForSingleObject(hEvent, INFINITE);
if (ret != WAIT_OBJECT_0)
{
// error
}

// Do stuff
}
}



You create the event object with the CreateEvent method and you signal the thread to do it's work by calling SetEvent.

You'll also need some other method to signal the thread to actually exit, for example you could have a second event object and use WaitForMultipleObjects instead.

However, from your example code, I'm not sure this is exactly what you want. It seems strange that you're sending the main thread a message which is just supposed to signal the worker thread again. Why not just do everything in a loop in the worker, avoiding the main thread altogether?

Share this post


Link to post
Share on other sites
Thanks for all of your help. I think I found the answer I was looking for, I use Sleep(0) [I was using Sleep(1)], this seems to make thread more multitasking friendly, and goes about as fast as when I don't use it. It still uses and endless loop, but thanks to "Sleep(0)" it runs a bit smoother now. How would I post some code on this forum? So you can see and try what I'm talking about.

Share this post


Link to post
Share on other sites
Quote:
Original post by mateo
Thanks for all of your help. I think I found the answer I was looking for, I use Sleep(0) [I was using Sleep(1)], this seems to make thread more multitasking friendly, and goes about as fast as when I don't use it. It still uses and endless loop, but thanks to "Sleep(0)" it runs a bit smoother now. How would I post some code on this forum? So you can see and try what I'm talking about.


I didnt read the whole thread (pun intended?), but if your threads needs to wait to a message from another thread, the way to do it is with semaphore.
I am not sure if sleep has a busy wait inside it, but I am sure semaphore doesnt have it.

Share this post


Link to post
Share on other sites
Sleep(0) does not make your thread more multitasking friendly. If there are no threads of equal priority in the 'ready' state, then Sleep(0) will not release your timeslice and will just return immediately. This means that threads of a lower priority won't be scheduled.

Sleep(1) means sleep for "at least" 1ms so that's probably why you noticed it wasn't running as smoothly.

I really think that what you want to do is best achieved using an event or semaphore, depending on whether you want the events to "queue" or not (if you want the "queueing" behaviour, then a semaphore is better, if you don't care then an event may be a bit simpler).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!