Killing a blocking thread ?

  • Thread starter Thread starter dahwoud
  • Start date Start date
D

dahwoud

Hi, i would like to know if there is a good way to stop (kill) a thread
that is blocked in a read operation, waiting for network incoming data
?

Thanks
 
Hi,

IMO, you get much better performance if you DO NOT use blocking reads. What
I do is to create a thread that enters a loop to read. Monitor a flag
inside the loop, and exit from the thread when/if the flag is set. This
kills the thread. Here is the code that I use (VB, but C# would be
similar):

'The ReadTCP class wraps the Tcpclient class Read method with a worker
thread

'that provides a method to terminate the thread when the application closes.

Friend Class ReadTCP

Friend Reading As Boolean 'Field to signal the state of the object

Friend Client As TcpClient

Friend Event DataAvailable(ByVal Buffer() As Byte)

Private ReadThread As Thread

'Call Start to create a new worker thread.

Friend Sub Start()

ReadThread = New Thread(AddressOf ReadThreadProc)

Reading = True

ReadThread.Start()

End Sub

'This is the worker thread that polls the Tcpclient.GetStream.Read method.

Private Sub ReadThreadProc()

Dim Buffer() As Byte

With Client.GetStream

Do Until Reading = False

If .DataAvailable = True Then

Try

ReDim Buffer(READ_BUFFER_SIZE)

..Read(Buffer, 0, READ_BUFFER_SIZE)

RaiseEvent DataAvailable(Buffer)

Catch ex As Exception

End Try

End If

Thread.Sleep(1)

Loop

End With

End Sub

End Class

End Class

Dick
--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Hi Dick,

IMO such "permanent loops" are very CPU consuming.
This means not the best for batery, performance of the rest of the device
and last not least I think it is better overall to wait for some kind of event.

Maybe I'm wrong (the hopefully someone will correct me) but I avoid such loops when ever it is possible.
Even a longer Sleep results in bad response times - so also not that idea.

But I confirm with you - it is also not a good idea to use blocking reads.
And I agree that such a "While ShouldRun construct" is a good idea.
I use it also in many cases - but the next line is most of the time WaitFor.....();

Manfred
 
The most optimal way is to use asynchronous socket calls,
but it's probably also the hardest way. It's really worth
learning, once you're used to async socket it works great.

Look at Begin* methods of the Socket class.
 
Hi,
IMO such "permanent loops" are very CPU consuming.
This means not the best for batery, performance of the rest of the device
and last not least I think it is better overall to wait for some kind of
event.
<<

Not at all. Notice the call to Thread.Sleep. This consume almost NO
processing time. I've done quite a bit of benchmarking, and I stand by my
statement that this code is MUCH better performing than the use of an
Asynchronous socket (or blocking calls). Have you actually tried these to
compare?

Dick

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Hi Dick,

I tried such things and a lot of Async things.
You can easyly try it yourself by just keep such code running (best with turned of display - since it consumes a lot of power and
flattens the results).
And on the other hand try async sockets (or wait handles or what ever is possible in the test).
Take care that no other processes keep the CPU on "full power" and watch how long the battery lasts.

Of course you (short) sleep gives other threads enough time to do their work - but the CPU does
not go to anykind of "low power state".

But I agree with you that this is
a.) much better than blocking calls
b.) very fast

As learned in the old times of assembler programming polling is always fast than any kind of exception (interrupt) handling.
Simple example: if you keep a phone at your ear you will allways be faster than me waiting for the ringtone befor taking of :-)

Since the scheduling mechanisms are very good in the current OS's such loops as yours do not stress the device to much.

But - and that is also a point which is for your approach - async things need deeper knowledge and are sometimes not so easy
to implement. So (also for me) it depends on the app what is better.
Easyer code is more stable - and therefore to prefer - and if the app runs on a device which has a power connection -
why take too much care about the battery. We for an example make a tracking application (GPS) and there is no need to
take care about battery. So we didn't optimze our code for battery lifetime - we want fast reactions and look for that.

Manfred
 
Hi,
Of course you (short) sleep gives other threads enough time to do their
work - but the CPU does
not go to anykind of "low power state".
<<

Sure. But, neither will it for other Async methods, assuming that there
actually is socket traffic -- that is a fair assumption, I think. And,
non-asynchronous methods have significant problems. So, you get what you
pay for.

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Dick Grier said:
Not at all. Notice the call to Thread.Sleep. This consume almost NO
processing time. I've done quite a bit of benchmarking, and I stand by my
statement that this code is MUCH better performing than the use of an
Asynchronous socket (or blocking calls). Have you actually tried these to
compare?

About your benchmarks, do you have anything that you can share? I'm sure
many people would be interested in such figures. Any reproducable code
you can post also?
What do you mean by "MUCH" better performance? Less latency? Higher
bandwith? Less CPU usage? Please share some details.

Have you thought anything around these results you have measured? Why
do you think sync sockets would perform better?

I don't know how async is implemented in netcf, but in the full framework
it benefits from I/O Completion ports, which, especially seen from a
system-wide view, has a superior performance compared to creating
several threads where each thread uses sync sockets.
 
Hi,
What do you mean by "MUCH" better performance? Less latency? Higher
bandwith? Less CPU usage? Please share some details.
<<

I didn't test CPU usage (there ain't no such thing as a free lunch,
TANSTAFL). However, if I recall correctly the bandwidth improvement was on
the order of 300- 400%. I don't have the code at hand, but I can dig it
out. I'll post a link in this thread when I get it posted -- this will take
several days due to my own bandwidth limitations.

Dick

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Dick Grier said:
Hi,

What do you mean by "MUCH" better performance? Less latency? Higher
bandwith? Less CPU usage? Please share some details.
<<

I didn't test CPU usage (there ain't no such thing as a free lunch,
TANSTAFL). However, if I recall correctly the bandwidth improvement was
on the order of 300- 400%. I don't have the code at hand, but I can dig
it out. I'll post a link in this thread when I get it posted -- this will
take several days due to my own bandwidth limitations.

It would be very interesting to see that code. You're actually stating that
sync
sockets perform 3-4 times better than async sockets?!? I haven't heard of
such limitations with async sockets before. I can't really think of why
async
sockets would perform less, I've often used async sockets and I have never
seen the problems you mention.
 
Hi Dick,

answering your two last post....

First - yes you are right - when there is allways traffic - than the difference between Sync and Async is almost nothing.
But this is neither a fact in all applications nor is it statet in the post of the thread starter.
It is like telling somebody - use snowchains they are allways better - without knowing where or when he drives :-)

Your 3 to 4 times better performance - maybe I know what you mean.
Assume that the async event is fired by an interrupt. So how (in simple words) is this implemented?
You wait for something.
The system remembers the fact that you wait - than your thread is marked as "needs no CPU time".
When an interrupt occures the system checks his list of "waiters" and if a thread is found waiting for that specific thing
this thread is marked as "needs soon CPU" (or even scheduled imideatly).
Anyhow the waiting thread gets control - or a little more precise the system prepares the executing environment for
that specific thread a "thread switch" occures.
And you are right - all these things take "a lot of" time. Searching for "waiters", context switching, and so on.

In older CPUs it took sometimes more time to switch the task than to do the work in the task :-)
Also OS designs did there work to slow down context switching.

Interrupt handling had the same problem - it was time consumming - and "high speed systems" were often designe in a "polling
000style".
You wrote a book about serial communication - therefore I use the UART as an example assuming that you know this peace of hardware.
Older UARTs (USARTs like 8051) did not have a buffer. So you had to take a lot of effort (especially with slow CPUs) to communicate
with a higher bandwith (baudrate). And if you really needed performance polling was the solution because interrupthandling was
significant slower.

But newer UARTs have a buffer of some bytes - and those bytes made the difference.
Now you could gain the same speed with interrupts - if you are doing it right.

And here we are - back to the 3 to 4 times more performance.
When (even with bufferd UARTs) you use interrupts for every single byte - there is almost no better performance than with unbufferd
UARTs. But if you do it like it should be done - you win.

And how (allways in async) should it be done?
You wait for the event (handle the interrupt) - and since the (time consumming) task swithch has taken place you collect all you can
get in your handler.
So if I "WaitForObject" and something happens - I don't consume one byte (or what ever it is) - I consume - and before I wait
again - I check if there is maybe more to consume.

By the way - modern systems implement the "WaitFor..." in such a manner - this means an "extension" to the simple way I wrote above!
Simple:
You wait for something (call WaitFor...)
The system remembers the fact that you wait - than your thread is marked as "needs no CPU time".
When an interrupt occures the system checks.....
"Modern":
You wait for something (call WaitFor...)
At the entrance of WaitFor.... occures a check if there is allready something ready to use.
In this case no TaskSwitch occures - the function returns imideatly to the caller.

So I don't beleave that you can get 3 to 4 times better performance with polling.
Especially if the developer does his async thing well (Wait - "read" all available - wait again) you will IMHO be only
a few percent faster.
And the more things that are going on - your "profite" gets less.

For an example - we have an app which has to:
Listen on an UDP socket, reading a GPS device, reading a handwriting recognition hardware (serial), a barcode reader
and checking for feedback from an external navigation application.
This would mean (in your approach) on loop for the UDP, one for GPS, one for the pen, one for the barcode reader
and last not least one for the navi - 5 permanent loops - and the app itself should also run (store things in a DB, display
information on a form, call webservices......).
And this app shows another thing - Barcode comes only sometimes in 0.0....% of the runtime.
Handwriting come also in only 0.0....% of the runtime.
For UDP - maybe it take 5 or more minutes till one information comes in.
And GPS send it's sentences also only once in a second.

So in speciall cases - your poll could bring slightly better performance - assuming permanent data.

But like Charles - I'm very interested in such benchmarks that show 3 to 4 times better performance.

I still agree with your
Use "blocking calls" is for sure (in most cases) the worst choice.

Regards

Manfred
 
Hi,
It would be very interesting to see that code. You're actually stating that
sync
sockets perform 3-4 times better than async sockets?!? I haven't heard of
such limitations with async sockets before. I can't really think of why
async
<<

No. I am making the reverse argument.

Dick

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Hi,
interrupt handling had the same problem - it was time consuming - and "high
speed systems" were often designe in a "polling
000style".
You wrote a book about serial communication - therefore I use the UART as an
example assuming that you know this peace of hardware.
Older UARTs (USARTs like 8051) did not have a buffer. So you had to take a
lot of effort (especially with slow CPUs) to communicate
with a higher bandwith (baudrate). And if you really needed performance
polling was the solution because interrupthandling was
significant slower.
<<

There is a basic misunderstanding here. Interrupts STILL are handled,
regardless of the methods used at the application level -- be they
synchronous or asynchronous, polled or via callback. That interrupt
overhead is the same regardless, and is done by the device drivers that the
OS hosts. The managed code in out .NET applications does not affect these
operations.

Out managed code ONLY deals with the interface between the application and
the OS, not the hardware; interrupts don't enter the picture. So, what we
(I) attempt to do is to make the use of these APIs as speedy as possible.
Personally, I don't care if my application consumes 50% of the available
processor time, as long as it executes as speedily as possible.
Multitasking on a PPC is somewhat constrained by the available resources, so
I make the assumption that I can make my own app run quickly, and I'll
concern myself with its impact on some other application's execution ONLY
when presented with the fact that this is important.

Dick

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Hi Dick,

there is no misunderstandig - of course uses the OS the interrupts.
But with the async approach you have a task or context switch.
A thing that you don't have with your polling.

I was using this example with the interrupts just by thinking that someone writing a book about serial communication
has some knowledge about those things and can therefore understand what I'm trying to say.
Since english is a foreign language I'm not very sure if my explanations are understandable - so I try to use examples like this.

In more precise words - if I WaitFor.... my taks get suspended - and when the OS found something for me
it has to return out of that function - which means a context switching.
And link in interrupt handling (where at least - depending on the CPU mode - the stack must be preservered) are
such time consuming things also needed at a context or task switch.
If I poll that things are not needed since the code stays in its own context.

Maybe we have a different look at the things - you say you don't care about other programms - since you have
your app - and that should run good an quick.
My point of view is that I never know what else is going on on that device.
And I never know what will run on the device where my SW runs. Will the user have other SW running (not depending on mine)?
Will there be tools like routing software, mailing software - or whatever - I don't know.
But I know from my own experience that programm A has problems when running concurrent with programm B.
Why? Both (ore one) of them didn't take care about other apps.

So like you say "Multitasking on a PPC is somewhat constrained by the available resources" I confirm with your words!
And I also know that resources on a PPC or SP are more limited than on a PC I have to take much more care about
other apps. For two reasons - one is the future (as stated above) - what will run there beside my app??
And the secound thing is - I build software that uses other apps (navigation). http://ttncf.pp-p.com is a part of it.

This means - I don't have to wait for the future - when my app runs - then it is almost clear that there will run at least 2
other apps (navogation and database) - and I try to keep my resource usage as low as possible to lower the impact to other apps!!

So from my point of view (even on desktops with "endless resources") it is some kind of "good style" to develope in
a way that needs as less resources as possible.

So you say: "I'll concern myself with its impact on some other application's execution ONLY when presented with the fact that this
is important."
And I say: a PPC is not designed to run only my app - so I assume it as a fact that there are also other apps running!

Cheers

Manfred
 
Hi,
Maybe we have a different look at the things - you say you don't care about
other programms - since you have
your app - and that should run good an quick.
My point of view is that I never know what else is going on on that device.
And I never know what will run on the device where my SW runs. Will the user
have other SW running (not depending on mine)?
Will there be tools like routing software, mailing software - or whatever -
I don't know.
But I know from my own experience that programm A has problems when running
concurrent with programm B.
Why? Both (ore one) of them didn't take care about other apps.
<<

Sure, different approaches can be appropriate to meet different needs. My
applications, in general, demand that they perform as quickly as possible.
This means that I make some assumptions about other applications
multitasking. However, Windows (and the underlying WindowsCE) does quite a
good job making sure that my application does not hog the processor to the
detriment of other applications. While the polled approach might seem to be
asking for trouble, it really isn't, IME.

Of course, if you go out of your way to cause trouble, you can do so. For
example, if you have a loop that does not sleep, you are not a good citizen
(esp. STAThread). If you have a thread that you run for long periods of
time at a high priority (esp. real-time), you are not a good citizen. Etc.
And, importantly, if you are writing code for a real-time process there are
occasions when you cannot do anything but your job.

When it comes down to a multithreaded application (not just one thread, but
multiple threads), we come to rely on the threading engine that the
Framework provides. This is only slightly different from multitasking-- and
the intellectual argument is similar. There we are doing thread context
switches in addition to process/application context switches.

You mention context switches. These are important. They are one of the
most expensive operations that can happen in Windows. Anything that we do
that avoids them will improve performance. But, the fact is, most of the
time they are beyond our control. Regardless of whether or not we have a
thread that is "tickling" or simply waiting on a notification, a switch WILL
occur between multiple processes, most of the time -- there are other things
that need to be done, even if it is only the bookkeeping that the framework
does.

At the end of the day you (the designer or engineer) will have to decide
what is the best approach to solve a problem. Often what appears to be
black and white, close up, actually is shades of gray at the appropriate
distance.

Dick

--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004. See
www.mabry.com/vbpgser4 to order.
 
Back
Top