Any way to restart a terminated thread

J

Jon Slaughter

Is there any way to start a terminated thread without using a pool or
creating a new thread object?

void counter()
{
clicks = 0;
clock.Start();
while (counterActive)
{
clicks++;
Thread.SpinWait(counterWaits);
}
clock.Stop();
}

double PointProfiler(int waits, int sleep)
{
counterWaits = waits;
while (counterThread.IsAlive) counterActive = false;
counterActive = true; clicks = 0;
counterThread.Start();
Thread.Sleep(sleep);
while (counterThread.IsAlive) counterActive = false;
return clicks / clock.Time;
}


I want to be able to start the counter thread each time but not create a new
thread(because of the performance overhead). I also don't want the counter
to run for ever so I need a way of restarting it. It seems that this is
impossible though? ;/

Is there any way to make it so that the thread is re-entrant? I tried to
suspend but suspend is obsolete and isn't working. If I do .Start() then
..Suspend() right after it I get 100% cpu usage as if it didn't suspend
anything.

It seems that I have no choice but to use a pool but I think that it might
cause some performance issues(I'm trying to time things as accurate as
possible). I can do what I want to do if I can let the counter thread run
continuously but now since I'm trying to integrate it as part of a gui I
need to only let it run when its needed. (and I think that creating a new
thread every time I need to do this is out of the questing(since I'll be
profiling several times in a row).
 
B

Ben Voigt [C++ MVP]

Jon Slaughter said:
Is there any way to start a terminated thread without using a pool or
creating a new thread object?

Why not use a manual-reset event? The thread will run as long as the event
remains set.
 
J

Jon Slaughter

BTW, I don't want the code to be asynchronous. I am trying to profile the
absolute timing of the thread and need to minimize other thread
interference. (and I don't need it in the background and don't care if it
freezes up the computer momentarily)

I also did this code in the main loop without a thread but the problem is
that I end up counting excess time from my clock routines. (Basically
clocking every click and it introduces significant error . I guess I could
do an average over it but already taking a bunch of averages... basically
with my old code using a thread I could ge around 10mhz using
Thread.SpinWait(1)... using my new code in the main loop I get max about
250khz using SpinWait(1).) If I can't find any satisfactory way to use
threads then I'll try to improve my main loop code.
 
J

Jon Slaughter

Ben Voigt said:
Why not use a manual-reset event? The thread will run as long as the
event remains set.

I'm not sure what your talking about? Could you please explain a little
more? I need the thread to be able to be re-entrant but not run
continuously. Essentially I need to use it like a function call but on a
different thread. (Because I need to time how long it takes to run in an
asychronous way).
 
J

Jon Skeet [C# MVP]

Jon Slaughter said:
Is there any way to start a terminated thread without using a pool or
creating a new thread object?

No. You need to either make the thread wait to have more work to do, or
start a new thread.

Why not just make it wait for more work to do, and reset the "clock"
(whatever that is) each time?
 
J

Jon Slaughter

Jon Skeet said:
No. You need to either make the thread wait to have more work to do, or
start a new thread.

Why not just make it wait for more work to do, and reset the "clock"
(whatever that is) each time?

What do you mean wait? How do you make the thread wait but not take up
cycles? If I had logic in there that prevents it from counting then it has
to do something else. If I make it goto sleep while its waiting then how do
I wake it back up in a timely fashion? I guess I could have my other thread
wait on it?

Would that save the cycles while the thread is inactive? Still seems like a
waste of cycles might be small enough that I can use it.

But even if I used sleep, since the minimal time is 1ms, and I'm doing tests
at the ns level, it causes each test to last atleast 1ms(cause I would have
to wait that long for the thread to "wake back up". This would take way to
long causing most of my tests to take an eternity.

Right now I'm simply timing things in a main loop and doing some averaging.
I think its working but I have a few issues when I'm timing a spinwait of a
very long durration.

Thanks,
Jon
 
J

Jon Skeet [C# MVP]

What do you mean wait? How do you make the thread wait but not take up
cycles?

Use Monitor.Wait or an Auto/ManualResetEvent. See the second half of
http://pobox.com/~skeet/csharp/threads/deadlocks.shtml
If I had logic in there that prevents it from counting then it has
to do something else. If I make it goto sleep while its waiting then how do
I wake it back up in a timely fashion? I guess I could have my other thread
wait on it?

The above page will explain.
But even if I used sleep, since the minimal time is 1ms, and I'm doing tests
at the ns level, it causes each test to last atleast 1ms(cause I would have
to wait that long for the thread to "wake back up". This would take way to
long causing most of my tests to take an eternity.

You're unlikely to get nanosecond accuracy with any system, to be
honest. In particular, at that level the scheduler is likely to be
significant.
Right now I'm simply timing things in a main loop and doing some averaging.
I think its working but I have a few issues when I'm timing a spinwait of a
very long durration.

Why do you even *have* a spinwait of a very long duration? The point
of a spinwait is to avoid context switching when you only want to wait
for a very short time.

Jon
 
W

Willy Denoyette [MVP]

Jon Slaughter said:
What do you mean wait? How do you make the thread wait but not take up
cycles? If I had logic in there that prevents it from counting then it
has to do something else. If I make it goto sleep while its waiting then
how do I wake it back up in a timely fashion? I guess I could have my
other thread wait on it?

Would that save the cycles while the thread is inactive? Still seems like
a waste of cycles might be small enough that I can use it.

But even if I used sleep, since the minimal time is 1ms, and I'm doing
tests at the ns level, it causes each test to last atleast 1ms(cause I
would have to wait that long for the thread to "wake back up". This would
take way to long causing most of my tests to take an eternity.

Right now I'm simply timing things in a main loop and doing some
averaging. I think its working but I have a few issues when I'm timing a
spinwait of a very long durration.

Thanks,
Jon


Adding to what Jon said, Windows is not a real time OS, that means that you
can't wait or sleep for a "precise" amount of time nor can you put a thread
asleep for 1msec. When calling Sleep say for 1 msec, then the thread will be
pre-empted and put asleep for at least the remainder of it's thread quantum.
Thread quantum's vary depending on the OS version and the HW (CPU) your code
runs on. The thread quantum ranges from 10 msecs. on single cores up to a
multiple of this on SMP or multicore system. Note that when other, higher
priority threads, are ready to run, that your thread might even sleep a lot
longer (seconds!). This all means that you can't even control precisely
*when* and for *how long* a thread will get a CPU quantum, this all is
controlled by the OS scheduler. You should consider this when using
synchronization primitives ( eg.. Monitors, WaitHandles etc...) to control
the "starting/stopping" of threads, it's not because one thread signals an
event, that the waiting thread will instantly be placed on the CPU, the
waiting thread will get it's slice when the scheduler sees fit, this can be
nearly immediately but also xx milliseconds later. Where xx depends on many
factor in the system, like the # of CPU's, the # of ready thread and their
priority, etc.....

Willy.
 
J

Jon Slaughter

Jon Skeet said:
Use Monitor.Wait or an Auto/ManualResetEvent. See the second half of
http://pobox.com/~skeet/csharp/threads/deadlocks.shtml


The above page will explain.


You're unlikely to get nanosecond accuracy with any system, to be
honest. In particular, at that level the scheduler is likely to be
significant.

I don't need nanosecond accuracy but nanosecond consistency. I need a way to
control the speed of communications. I can do this quite easily with spin
wait. Doesn't matter if its not perfect cause its the best I can do.
Why do you even *have* a spinwait of a very long duration? The point
of a spinwait is to avoid context switching when you only want to wait
for a very short time.

Its the only way to get the control over timing. I suppose after one msec I
could start using sleep but thats pretty unregular and chances are I'll
never use it anyways...
 
J

Jon Slaughter

Willy Denoyette said:
Adding to what Jon said, Windows is not a real time OS, that means that
you can't wait or sleep for a "precise" amount of time nor can you put a
thread asleep for 1msec. When calling Sleep say for 1 msec, then the
thread will be pre-empted and put asleep for at least the remainder of
it's thread quantum. Thread quantum's vary depending on the OS version and
the HW (CPU) your code runs on. The thread quantum ranges from 10 msecs.
on single cores up to a multiple of this on SMP or multicore system. Note
that when other, higher priority threads, are ready to run, that your
thread might even sleep a lot longer (seconds!). This all means that you
can't even control precisely *when* and for *how long* a thread will get a
CPU quantum, this all is controlled by the OS scheduler. You should
consider this when using synchronization primitives ( eg.. Monitors,
WaitHandles etc...) to control the "starting/stopping" of threads, it's
not because one thread signals an event, that the waiting thread will
instantly be placed on the CPU, the waiting thread will get it's slice
when the scheduler sees fit, this can be nearly immediately but also xx
milliseconds later. Where xx depends on many factor in the system, like
the # of CPU's, the # of ready thread and their priority, etc.....

I know I can't get precise control but using my method at the moment I can
get some control. I can get within a few % on average of any speed I want up
to, on my system, of about atleast 1mhz. (with an empty code block its about
250mhz but when I actually add something to do it will reduce it).

Its better than running a communications at < 1khz and still being unstable.
 
W

Willy Denoyette [MVP]

Jon Slaughter said:
I know I can't get precise control but using my method at the moment I can
get some control. I can get within a few % on average of any speed I want
up to, on my system, of about atleast 1mhz. (with an empty code block its
about 250mhz but when I actually add something to do it will reduce it).

Its better than running a communications at < 1khz and still being
unstable.


Not sure what you mean by this, actually you don't (can't) control the
counting thread, which is the whole point of your question right? Actually
what you are doing is simply count how long it takes to run a piece of code,
that is - SpinLock and increment a counter - in an loop, no other thread
comes in the picture. Once you have to synchronize the counting thread's
activity from another thread you will need to use some synchronization
mechanism, and this is where you will get confronted by the restrictions and
limitations Windows (or any other non real-time OS) as explained above.


Willy.
 
J

Jon Slaughter

Willy Denoyette said:
Not sure what you mean by this, actually you don't (can't) control the
counting thread, which is the whole point of your question right? Actually
what you are doing is simply count how long it takes to run a piece of
code, that is - SpinLock and increment a counter - in an loop, no other
thread comes in the picture. Once you have to synchronize the counting
thread's activity from another thread you will need to use some
synchronization mechanism, and this is where you will get confronted by
the restrictions and limitations Windows (or any other non real-time OS)
as explained above.

No, I am synchronozing it with hardware. But since its synchronous
communications and I'm the master communicator it doesn't have to have be
tightly timed. But I need a way to do timely communications I cannot just
do it fast as possible because the device itself may not be able to
communicate at that rate. But I can't just put some arbitrarily delay
because it might be to slow or to fast on different systems.

By having some abilility to get an average consistency and an upper bound on
the speed I have atleast partial control.

The idea is simply to run a function at an approximate speed beyond 1ms
resolution.

Essentially all it boils down to is

communicate with hardware,
delay,
communicate with hardware,
delay,
communicate with hardware,
delay,
communicate with hardware,
delay,
communicate with hardware,
delay,
communicate with hardware,
delay,
communicate with hardware,
delay,

But delay how much? Since I can't get around the fact that the delay might
always be larger than I want but I have no choice... but its not critical
anyways. But I still need to set a delay that will give me an upper bound
on the speed.

For example, I know if I used delay = SpinWait(1) on my system, supposing
communicate wiht hardware takes 0 cycles that the routine will run at
250mhz. (Later on I'll add some the ability to time the communication to get
a more accurate reading).

If SpinWait is something like 1000000 then it will run about 8khz. Sure it
might run at 7 khz here and 9khz there(cause my timing was an avg value) and
sure in some cases it might introduce a delay of 1s... but theres nothing I
can do about.

The main thing I don't like is that the delay has to waste cycles to
actually delay. But I guess thats the price I have to pay...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top