How to detect if a thread is still running

When I create a thread I get a pointer to an SDL_Thread structure.
It seems to me I can use the status field to detect whether the thread has
finished, but to use it, I have to include SDL_Thread_c.h which seems not to
be meant to be included.

So what is the correct, platform independent, way to do this?

Huib-Jan

When I create a thread I get a pointer to an SDL_Thread structure.
It seems to me I can use the status field to detect whether the thread has
finished, but to use it, I have to include SDL_Thread_c.h which seems not to
be meant to be included.

So what is the correct, platform independent, way to do this?

I usually have a global variable and set it when I want the thread to quit.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

When I create a thread I get a pointer to an SDL_Thread structure.
It seems to me I can use the status field to detect whether the thread
has

finished, but to use it, I have to include SDL_Thread_c.h which seems
not to

be meant to be included.

So what is the correct, platform independent, way to do this?

I usually have a global variable and set it when I want the thread to
quit.

I don’t want the thread to quit. It is doing a lengthy calculation for me
and it quits when it has finished. It would have been easiest for me if
there were some function int SDL_ThreadStatus (SDLThread *thread) that
allows me to get the status of the thread without having to add a global
flag and a mutex to protect that flag.

So what is the correct, platform independent, way to do this?
I usually have a global variable and set it when I want the thread to
quit.

I dearly hope you mean a conditional variable or the like rather than
periodically polling a global for a condition to happen!

I don’t want the thread to quit. It is doing a lengthy calculation for me
and it quits when it has finished. It would have been easiest for me if
there were some function int SDL_ThreadStatus (SDLThread *thread) that
allows me to get the status of the thread without having to add a global
flag and a mutex to protect that flag.

What sorts of operations are you doing when it’s busy vs. when it’s not
busy? Depending upon your answer, there may be other ways, but it doesn’t
seem like a good idea to check status on something and wait for it to
finish - if indeed that’s what you’re doing. A conditional variable via
SDL is probably your answer. Let me know what it’s doing based upon the
thread’s busy/nonbusy status.

–>Neil-------------------------------------------------------------------------------
Neil Bradley What are burger lovers saying
Synthcom Systems, Inc. about the new BK Back Porch Griller?
ICQ #29402898 “It tastes like it came off the back porch.” - Me

— Huib-Jan Imbens wrote:

I don’t want the thread to quit. It is doing a
lengthy calculation for me
and it quits when it has finished. It would have
been easiest for me if
there were some function int SDL_ThreadStatus
(SDLThread *thread) that
allows me to get the status of the thread without
having to add a global
flag and a mutex to protect that flag.

  1. If you DON’T want the thread to quit, have it do
    something else instead of quit (i.e. have it set a
    flag asking the main thread for more stuff to
    calculate.)

  2. To determine if the a thread is still running, you
    actually shouldn’t NEED a mutex: There is one point
    in time where the thread will announce it is about to
    exit. around that time, the main thread has no
    buisness WRITING to that flag, also that flag does not
    need to be kept coherent with anything else, so it
    that scenario, there is (strictly speaking) no need
    for the mutex. Mutexes are primarily needed when the
    direction of communications are in question, or when
    the data being shared by multiple threads can exist in
    an undefined state. Bare in mind that with one-way
    sequential guarenteed data between two threads,
    two-way communication (and therefore mutexes) are
    probably required.

For a mutex-less exit status, the code should look
something like this:

bool IsCalculateThreadAboutToExit = true;

int StartCalculateThread(void )
{
uint i;
for(i=0; i<1000000; i++)
{
/
Calculate Stuff /
}
/
I’m about to exit: tell the world! */
IsCalculateThreadAboutToExit = true;
}

void LaunchCalculateThread()
{
IsCalculateThreadAboutToExit = false;
SDL_CreateThread(StartCalculateThread);
}

bool IsThreadStillRunning()
{
return (!IsCalculateThreadAboutToExit);
}

Best Regards,

-Loren__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better

For a mutex-less exit status, the code should look
something like this:
bool IsCalculateThreadAboutToExit = true;
int StartCalculateThread(void )
{
uint i;
for(i=0; i<1000000; i++)
{
/
Calculate Stuff /
}
/
I’m about to exit: tell the world! */
IsCalculateThreadAboutToExit = true;
}

void LaunchCalculateThread()
{
IsCalculateThreadAboutToExit = false;
SDL_CreateThread(StartCalculateThread);
}

bool IsThreadStillRunning()
{
return (!IsCalculateThreadAboutToExit);
}

I realize this is only an example, but with the "IsThreadStillRunning"
procedure, I feel compelled to say that that’d peg the processor at 100%
utilization. Andi t begs the question, if a subordinate thread is spawned
off, only to be waited on by another thread, why was the subordinate
thread created in the first place?

There are very few reasons to create another thread for something, and
more often I see thread abuse than use. It might be tempting (whizzy/cool)
to use a thread, but there are so few circumstances when it’s actually
needed that when someone says they need a thread for something, more often
than not they don’t!

–>Neil-------------------------------------------------------------------------------
Neil Bradley What are burger lovers saying
Synthcom Systems, Inc. about the new BK Back Porch Griller?
ICQ #29402898 “It tastes like it came off the back porch.” - Me

— Neil Bradley wrote:

For a mutex-less exit status, the code should look
something like this:
bool IsCalculateThreadAboutToExit = true;
int StartCalculateThread(void )
{
uint i;
for(i=0; i<1000000; i++)
{
/
Calculate Stuff /
}
/
I’m about to exit: tell the world! */
IsCalculateThreadAboutToExit = true;
}

void LaunchCalculateThread()
{
IsCalculateThreadAboutToExit = false;
SDL_CreateThread(StartCalculateThread);
}

bool IsThreadStillRunning()
{
return (!IsCalculateThreadAboutToExit);
}

I realize this is only an example, but with the
"IsThreadStillRunning"
procedure, I feel compelled to say that that’d peg
the processor at 100%
utilization.

Umm… IsThreadStillRunning() is simply an accessor.
It doesn’t loop, or anything like that… The user
wanted to know “is the other thread still running”…
said nothing about WHEN he was quereing the status of
the thread or HOW OFTEN. Admittedly, this function
does have to be quereied, but it’s stupid to assume
that the main thread won’t be doing something else, or
that the latency required must be so low that the main
thread must busy-wait on it’s value. There are better
methods than polling a variable, but most games (SDL
is used primarily for games) have main-loops, and
these main loops can be used for this type of polling
in situations that don’t require low latency.
Typically threads should not be used where extremely
low latency is required.

Andi t begs the question, if a
subordinate thread is spawned
off, only to be waited on by another thread, why was
the subordinate
thread created in the first place?

Who said anything about what the main thread was
doing?

There are very few reasons to create another thread
for something, and
more often I see thread abuse than use. It might be
tempting (whizzy/cool)
to use a thread, but there are so few circumstances
when it’s actually
needed that when someone says they need a thread for
something, more often
than not they don’t!

I agree that I have seen threads abused in many
instances, but they do have their place… Especially
for asynchronous data processing.

–>Neil

Cheer,

-Loren__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better

bool IsCalculateThreadAboutToExit = true;

return (!IsCalculateThreadAboutToExit);
I realize this is only an example, but with the
"IsThreadStillRunning"
Umm… IsThreadStillRunning() is simply an accessor.
It doesn’t loop, or anything like that…

True… the “return” I read as a “while”. I’m just wondering what the
calling thread is doing with it.

The user
wanted to know “is the other thread still running”…
said nothing about WHEN he was quereing the status of
the thread or HOW OFTEN.

Right, however rather than just answering the question, I’d like to pop up
a stack and understand how it is used before making a recommendation on
implementation. It may be that a global is all that’s needed, but more
often than not (as you acknowledge), people tend to write code that spin
locks on a variable until it changes. Also, don’t forget to declare it
volatile. :wink:

does have to be quereied, but it’s stupid to assume
that the main thread won’t be doing something else, or
that the latency required must be so low that the main
thread must busy-wait on it’s value.

If more people “correctly” used threads (I.E. not spinning on
global variables or waking up every 10 milliseconds to check a variable)
then it certainly would be stupid, but gauging by the amount of code I’ve
seen that does stuff like:

while (IsThreadRunning)

And:

while (IsThreadRunning)
{
	Sleep(10);
}

I can’t help but injerject that there are always better methods than this.

There are better
methods than polling a variable, but most games (SDL
is used primarily for games) have main-loops, and
these main loops can be used for this type of polling
in situations that don’t require low latency.

If it’s spin locking on the variable, it uses CPU time - unnecessarily.

Typically threads should not be used where extremely
low latency is required.

In preemptive OSes that are inherently unpredictable (I.E. Linux, FreeBSD,
Windows, OS X), you’re at the mercy of the OS’s scheduler anyway.
Spinlocking on a variable will not help. A Better way to reduce the
latency would be to have the main thread wait on a conditional variable,
and the subordinate thread do a conditional variable set and a delay of 0,
which will immediately exit that thread and give other threads a chance to
run. This is a much faster approach than a spinlock check.

Andi t begs the question, if a
subordinate thread is spawned
off, only to be waited on by another thread, why was
the subordinate
thread created in the first place?
Who said anything about what the main thread was
doing?

That’s why I said “if the subordinate thread”… I’m making an educated
guess based on past experiences that it’s doing a spin lock, which isn’t
good.

to use a thread, but there are so few circumstances
needed that when someone says they need a thread for
than not they don’t!
I agree that I have seen threads abused in many
instances, but they do have their place… Especially
for asynchronous data processing.

Oh yeah. My favorite “other thread” is for sound processing in a game.
It’s especially cool to see SDL have it as a separate thread rather than
requiring the user to “push sound out the port periodically”. Immediately
in my mind when I saw this, I thought - “These SDL guys ROCK.” :wink:

–>Neil-------------------------------------------------------------------------------
Neil Bradley What are burger lovers saying
Synthcom Systems, Inc. about the new BK Back Porch Griller?
ICQ #29402898 “It tastes like it came off the back porch.” - Me

— Neil Bradley wrote:

bool IsCalculateThreadAboutToExit = true;

return (!IsCalculateThreadAboutToExit);
I realize this is only an example, but with the
"IsThreadStillRunning"
Umm… IsThreadStillRunning() is simply an
accessor.
It doesn’t loop, or anything like that…

True… the “return” I read as a “while”. I’m just
wondering what the
calling thread is doing with it.

The user
wanted to know “is the other thread still
running”…
said nothing about WHEN he was quereing the status
of
the thread or HOW OFTEN.

Right, however rather than just answering the
question, I’d like to pop up
a stack and understand how it is used before making
a recommendation on
implementation. It may be that a global is all
that’s needed, but more
often than not (as you acknowledge), people tend to
write code that spin
locks on a variable until it changes. Also, don’t
forget to declare it
volatile. :wink:

Yup!.. my bad… :frowning:

does have to be quereied, but it’s stupid to
assume
that the main thread won’t be doing something
else, or
that the latency required must be so low that the
main
thread must busy-wait on it’s value.

If more people “correctly” used threads (I.E. not
spinning on
global variables or waking up every 10 milliseconds
to check a variable)
then it certainly would be stupid, but gauging by
the amount of code I’ve
seen that does stuff like:

while (IsThreadRunning)

And:

while (IsThreadRunning)
{
Sleep(10);
}

I can’t help but injerject that there are always
better methods than this.

I hear you, but this seems like giving each driver a
disertaion on safe driving any time they visit the gas
pump… Most people probably don’t drive as safely as
they could, but that probably won’t help… People are
unfortunately comfortable with their bad habbits
despite good advice…

There are better
methods than polling a variable, but most games
(SDL
is used primarily for games) have main-loops, and
these main loops can be used for this type of
polling
in situations that don’t require low latency.

If it’s spin locking on the variable, it uses CPU
time - unnecessarily.

Most games are perpetually in game loops which often
look like this:

while(!AreWeExiting())
{
CheckOnInputs();
CheckOnOtherStuff();
if(AreWeInFocus())
{
if(!IsGamePaused())
{
UpdateGame();
}
UpdateUI();
if(DidAnythingChange())
{
UpdateScreen();
}
if(DoWeHaveTimeToBurn())
{
Sleep(SomeTime);
}
}
else
{
Sleep(QuiteAWhile);
}
}

Or basically one giant spin-lock… it isn’t super
efficient, but alot of the things that cause it to
Pause are generated by the main thread itself, and
can’t be signaled by the OS… There may be better
ways, but I haven’t seen one that’s general purpose
enough to work with a full-blown game, and the gains
are usually minimal compared to the status quo.

Typically threads should not be used where
extremely
low latency is required.

In preemptive OSes that are inherently unpredictable
(I.E. Linux, FreeBSD,
Windows, OS X), you’re at the mercy of the OS’s
scheduler anyway.
Spinlocking on a variable will not help. A Better
way to reduce the
latency would be to have the main thread wait on a
conditional variable,
and the subordinate thread do a conditional variable
set and a delay of 0,
which will immediately exit that thread and give
other threads a chance to
run. This is a much faster approach than a spinlock
check.

In theory, I agree. In practice, this has one fatal
flaw: If the main thread is waiting on a conditional
variable than it’s “too busy” (or more accuratly “too
asleep”) to do anything useful, which defeats the
whole purpose of having the separate thread. If
you’re writting a server, whose whole life is going to
revolve around waiting for input, and responding to
it, then your point makes a good deal of sense, but
when the main loop has more to worry about than the
status of some threads and some I/O, it doesn’t seem
to work.

to use a thread, but there are so few
circumstances

needed that when someone says they need a thread
for

than not they don’t!
I agree that I have seen threads abused in many
instances, but they do have their place…
Especially
for asynchronous data processing.

Oh yeah. My favorite “other thread” is for sound
processing in a game.
It’s especially cool to see SDL have it as a
separate thread rather than
requiring the user to “push sound out the port
periodically”. Immediately
in my mind when I saw this, I thought - “These SDL
guys ROCK.” :wink:

Yes, I thought that was quite clever also…

:slight_smile:

-Loren__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better

I can’t help but injerject that there are always
better methods than this.
I hear you, but this seems like giving each driver a
disertaion on safe driving any time they visit the gas
pump… Most people probably don’t drive as safely as
they could, but that probably won’t help… People are
unfortunately comfortable with their bad habbits
despite good advice…

Yeah, I know. ;-( But there have been at least a couple of people who have
had their ways changed by a simple comment just because they didn’t know
those options existed! Continuous self improvement… helping eachother is
a good thing, even if only a small percentage of the people who hear it
actually get it and internalize it!

while(!AreWeExiting())
{
CheckOnInputs();
CheckOnOtherStuff();
if(AreWeInFocus())
{
if(!IsGamePaused())
{
UpdateGame();
}
UpdateUI();
if(DidAnythingChange())
{
UpdateScreen();
}
if(DoWeHaveTimeToBurn())
{
Sleep(SomeTime);
}
}
else
{
Sleep(QuiteAWhile);
}
}
Or basically one giant spin-lock… it isn’t super
efficient, but alot of the things that cause it to
Pause are generated by the main thread itself, and
can’t be signaled by the OS…

What you have above isn’t so bad - due to the sleeps. That’ll put the
thread to sleep, therefore relinquishing CPU time. I don’t consider this a
spin lock since there isn’t anything that spins inside a thread, and it
really is using the OS to sleep. Another alternative is to use a semaphore
and have a timer do a post to the semaphore, and the main loop to wake up
on that semaphore. Probably negligible differences between the approach
above and the semaphore approach.

There may be better
ways, but I haven’t seen one that’s general purpose
enough to work with a full-blown game, and the gains
are usually minimal compared to the status quo.

Checking on focus seems like something that could be completely eliminated
as a runtime check since messages are dispatched for switching focus. But
you’re right - there isn’t much in the way of improvement that could be
made. At least under DOS I could do controller input via interrupts so I’d
never check for any keys being pressed. I’d just get updates. :wink:

In preemptive OSes that are inherently unpredictable
(I.E. Linux, FreeBSD,
Windows, OS X), you’re at the mercy of the OS’s
scheduler anyway.
set and a delay of 0,
which will immediately exit that thread and give
other threads a chance to
run. This is a much faster approach than a spinlock
check.
In theory, I agree. In practice, this has one fatal
flaw: If the main thread is waiting on a conditional
variable than it’s “too busy” (or more accuratly “too
asleep”) to do anything useful, which defeats the
whole purpose of having the separate thread.

Thank you for so eloquently supporting my prior statement of threads most
often shouldn’t be used. :wink:

Oh yeah. My favorite “other thread” is for sound
processing in a game.
It’s especially cool to see SDL have it as a
separate thread rather than
requiring the user to “push sound out the port
periodically”. Immediately
in my mind when I saw this, I thought - “These SDL
guys ROCK.” :wink:
Yes, I thought that was quite clever also…

Been doing this in DOS land since '91! It’s especially useful when doing
emulation of sound chips and whatnot - just write to the device and the
audio will get updated when it’s needed. Seems so natural to be a separate
thread!

–>Neil-------------------------------------------------------------------------------
Neil Bradley What are burger lovers saying
Synthcom Systems, Inc. about the new BK Back Porch Griller?
ICQ #29402898 “It tastes like it came off the back porch.” - Me

There are very few reasons to create another thread for something, and
more often I see thread abuse than use. It might be tempting (whizzy/cool)
to use a thread, but there are so few circumstances when it’s actually
needed that when someone says they need a thread for something, more often
than not they don’t!

May be I should have explained the situation in which I intended to use
SDL_ThreadIsRunning () a bit more.
The code below shows the relevant parts of my event loop (which is run in
the main thread).

ready = SDL_FALSE;
while (!ready) {
// redraw all areas that have been invalidated
if (gView) gView->Update ();

// perform all tasks
SFTaskManager::GlobalTaskManager ().DoTasks ();

// handle network events
SFTCPClientManager::GlobalTCPClientManager ().DoTCPClients ();

// poll events and handle them
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_QUIT: /* Quit now */
ready = SDL_TRUE;
break;
case SDL_KEYUP:
SFKeyboardHandlerManager::GlobalKeyboardHandlerManager ().HandleKeyUp
(event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.unicode);
break;
case SDL_MOUSEBUTTONUP:
if (gView) {
gView->HandleMouseMove (*gView, event.button.x, event.button.y);
gView->HandleMouseUp (*gView, event.button.button);
}
break;
case …:
break;
}
}
}

The thread that I want to know the status of, is started somewhere deep in
the HandleMouseUp call and is calculating a chess move. That takes some
time. In the mean time I want the GUI to stay responsive. Eg. one of the
tasks registered to the GlobalTaskManager updates a chess clock on the
screen and I don’t want that clock to pause while the move is being
calculated. In another one of the tasks registered to the GlobalTaskManager
I want to check whether the chess thread has finished so I can perform the
move.

Latency is not an issue at all. Besides I don’t see a reason why latency
would be large unless the GUI is very busy.

Of course there are ways to do this without a thread. I could split up the
move calculation in small pieces and call those pieces from a task. I could
also make a copy of my event loop and call that copy every now and then from
the chess code. In both cases the chess code would be a lot more complicated
and dependent on this particular GUI.

int StartCalculateThread(void )
{
uint i;
for(i=0; i<1000000; i++)
{
/
Calculate Stuff /
}
/
I’m about to exit: tell the world! */
IsCalculateThreadAboutToExit = true;
}

void LaunchCalculateThread()
{
IsCalculateThreadAboutToExit = false;
SDL_CreateThread(StartCalculateThread);
}

bool IsThreadStillRunning()
{
return (!IsCalculateThreadAboutToExit);
}

Ok, let us assume some imaginary OS and hardware where:

  1. a bool is stored as 4 bytes.
  2. true is stored as 0xffffffff, false is stored as 0x00000000
  3. !IsCalculateThreadAboutToExit is compiled as IsCalculateThreadAboutToExit
    == 0
  4. hardware stores 2 bytes at a time (may be only in special cases where the
    4 bytes are in two different pages)

Now with a dying thread I risk that I get a context switch after the first
half of IsCalculateThreadAboutToExit has been set. So inthe main thread
IsThreadStillRunning () will return true.
So in some imaginary app, I might immediately, that is in the same timeslice
start a new thread. After another context switch the dying thread would be
setting the other half of IsCalculateThreadAboutToExit and I would assume
that the other thread would have finished as well.

May be this guaranteed to never happen but I prefer not to think about these
issues and rely on an API call that someone smarter than me has written and
that many smart people have reviewed.

Also, don’t forget to declare it volatile. :wink:

That is a good point, but probably not very important in my case because I
would check it only once each event loop deep down in
SFTaskManager::GlobalTaskManager ().DoTasks ();, so I am confident that my
compiler will not be able to optimize the check away.
However the very fact that you have to think about such subtleties made me
ask whether I overlooked some SDL API call.

Huib-Jan