Processes Vs Threads

Hi,

As I am a new QNX user I would appreciate it if somebody could outline the
circumstances when tasks should be written as a process or when they should
be written as a thread? I understand the concepts, but as I am designing a
robotic system with many different elements I would like to hear opinions
from the people who know their stuff before I write the different parts as
one or the other and put them all together as a single system.

All opinions appreciated!

RK

RonanK wrote:

Hi,

As I am a new QNX user I would appreciate it if somebody could outline the
circumstances when tasks should be written as a process or when they should
be written as a thread? I understand the concepts, but as I am designing a
robotic system with many different elements I would like to hear opinions
from the people who know their stuff before I write the different parts as
one or the other and put them all together as a single system.

I’ll bite.

First let’s clear up what we’re talking about. Threads and Processes (at least
under QNX) are not only not mutually exclusive, they are in fact
inter-dependant (you can not have a process with 0 threads for instance); and
(in current implementations at least) you cannot have a thread without a process.

It is helpful to view processes as containers for threads (i.e. use the term
“process” to refer to such things as a “tasks” memory resources, fds, etc. and
threads to refer to execution contexts within a process).

So given this context, your question becomes “Under what circumstances would one
choose to share a single process space with multiple threads ?”. Of course,
being a design question, the answer is not simple.

I have a basic rule of thumb that I follow, and that is:

“Don’t multithread clients, do multithread servers”. Of course, many servers
are also clients, so this basic rule-of-thumb has a problem right out of the
gate (but it is useful as a guiding principle).

Refinements of this basic rule-of-thumb are:

  1. Only multithread servers when it is really required (i.e. not just because
    it’s cool). This means that if the server controls a serial access only
    resource don’t multithread your server.

  2. I have never found a good reason to multithread a client (although I have
    found a few bad reasons :slight_smile:

Essentially the conditions that make threads a “win” are when the server is
either CPU bound or controls access to multiple resources that can operate in
parallel. A threaded design will always be more bug prone than a cleanly
designed single thread event based design; however, if finely grained
parallelism is required, threads can be the only way to get there.

The bottom line is, if you don’t have a compelling reason to use multiple
threads per process, don’t. It’ll typically be very obvious when you need to
write a multithreaded process, and it probably won’t happen very often.

You should be happy if you are never required to write a multithreaded server,
just as you would be happy to never have to use your jack on your car to change
a tire at the side of the road on a rainy night (which doesn’t say anything bad
about jacks - in fact when you need your jack you’ll be happy you have it :slight_smile:

Rennie

Hi Rennie…

Rennie Allen wrote:

You should be happy if you are never required to write a multithreaded
server, just as you would be happy to never have to use your jack on
your car to change a tire at the side of the road on a rainy night
(which doesn’t say anything bad about jacks - in fact when you need your
jack you’ll be happy you have it > :slight_smile:

Interesting way to put this in words! Amusing too! Humm… you still
have a sense of humor I see… great.

I have an observation/question however, when you have interrupts, would
you or wouldn’t you use threads, one for each interrupt service? How
would you do otherwise? Have a number of processes comunicating via
IPC? This is what I used to do back in the QNX4.2x days… Just curious
to see your take on this.

Regards…

Miguel.

Rennie

Miguel Simon wrote:

Hi Rennie…

Interesting way to put this in words! Amusing too! Humm… you still
have a sense of humor I see… great.

I have an observation/question however, when you have interrupts, would
you or wouldn’t you use threads, one for each interrupt service?

I would probably not use threads. I would probably use InterruptAttachEvent,
and MsgReceive with a single thread; of course, with a single threaded server
it would be more difficult to predict the worst case interrupt service time
(since you have to allow for the fact the server may have just received a
message from a client when the interrupt happens).

If one designs servers to have short paths through all of the services (hardware
services as well as client services), the worst case interrupt response is
usually small enough that it is not a problem.

How

would you do otherwise?

See above.

Hi Rennie…

Rennie Allen wrote:

I would probably not use threads. I would probably use
InterruptAttachEvent, and MsgReceive with a single thread; of course,

Yes, but MsgReceive is by definition a thread, separte from your main()
thread, correct?

Regards…

Miguel.


with a single threaded server it would be more difficult to predict the
worst case interrupt service time (since you have to allow for the fact
the server may have just received a message from a client when the
interrupt happens).

If one designs servers to have short paths through all of the services
(hardware services as well as client services), the worst case interrupt
response is usually small enough that it is not a problem.

How

would you do otherwise?


See above.

Miguel Simon wrote:

Hi Rennie…

Rennie Allen wrote:

I would probably not use threads. I would probably use
InterruptAttachEvent, and MsgReceive with a single thread; of course,

Yes, but MsgReceive is by definition a thread, separte from your main()
thread, correct?

No. I am referring to one thread with a MsgReceive that dispatches to
different services. At one point it might dispatch a service for a client,
at another point it might dispatch a service for an interrupt (which is
why the worst case interrupt service latency is the longest of all the
services the resource manager provides plus the length of the interrupt
service routine (until the hardware is serviced). Again, if all services
have short bounds, this isn’t typically an issue.

Rennie

Miguel Simon <simon@ou.edu> wrote:

Hi Rennie…

Rennie Allen wrote:

I would probably not use threads. I would probably use
InterruptAttachEvent, and MsgReceive with a single thread; of course,

Yes, but MsgReceive is by definition a thread, separte from your main()
thread, correct?

Absolutely not.

MsgReceive() is, by definition, a library call (which happens to be
a kernel call) and a blocking point to receive messages/notification.

It is where a thread comes to a stop until it gets something new
to process.

Your basic server:

int main()
{
// setup
while(1)
{
rcvid = MsgReceive();
// process message
MsgReply(rcvid, …);
}
}

One thread.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hi David…

OK, I see. What I do is get that going in a thread by itself while the
main thread goes on to do other things (I had to go back and look at my
code). I do indeed have the thread with MsgReceive() going manually.

Thanks.

Miguel.


David Gibbs wrote:

Miguel Simon <> simon@ou.edu> > wrote:

Hi Rennie…


Rennie Allen wrote:

I would probably not use threads. I would probably use
InterruptAttachEvent, and MsgReceive with a single thread; of course,


Yes, but MsgReceive is by definition a thread, separte from your main()
thread, correct?


Absolutely not.

MsgReceive() is, by definition, a library call (which happens to be
a kernel call) and a blocking point to receive messages/notification.

It is where a thread comes to a stop until it gets something new
to process.

Your basic server:

int main()
{
// setup
while(1)
{
rcvid = MsgReceive();
// process message
MsgReply(rcvid, …);
}
}

One thread.

-David

Miguel Simon wrote:

Hi David…

OK, I see. What I do is get that going in a thread by itself while the
main thread goes on to do other things (I had to go back and look at my
code). I do indeed have the thread with MsgReceive() going manually.

If you want minimal latency, you could use InterruptWait in your dedicated
thread, rather than MsgReceive.

Rennie

“Rennie Allen” <rgallen@attbi.com> wrote in message
news:bghcuo$f01$1@inn.qnx.com

  1. I have never found a good reason to multithread a client (although I
    have
    found a few bad reasons > :slight_smile:

You must have never written a GUI ‘client’ (that is, any application with
interactive user interface that allows doing several things at once) then.

– igor

One well known ‘rule of thumb’ is that for a multithreaded application you
should have one thread per CPU, plus one thread per an outstanding I/O
request, plus one. Based on that, you can come up with a number of ways to
split your application into threads. There are good books on the subject,
reading one of them will be much more helpful than asking for opinions in
newsgroups.

– igor

“RonanK” <ronan.kennelly@nuigalway.ie> wrote in message
news:bg2vbg$l0r$1@inn.qnx.com

Hi,

As I am a new QNX user I would appreciate it if somebody could outline the
circumstances when tasks should be written as a process or when they
should
be written as a thread? I understand the concepts, but as I am designing a
robotic system with many different elements I would like to hear opinions
from the people who know their stuff before I write the different parts as
one or the other and put them all together as a single system.

All opinions appreciated!

RK

Igor Kovalenko wrote:

“Rennie Allen” <> rgallen@attbi.com> > wrote in message
news:bghcuo$f01$> 1@inn.qnx.com> …

  1. I have never found a good reason to multithread a client (although I
    have
    found a few bad reasons > :slight_smile:


    You must have never written a GUI ‘client’ (that is, any application with
    interactive user interface that allows doing several things at once) then.

As a matter of fact I have written gui clients. I am not suggesting there
aren’t good reasons to thread a client, only that I haven’t encountered
one yet. Background processes for gui’s are not automatically a good use
for threads, for instance some background processes are better served by
spawning a new process. I am sure there are cases where threads are the
best solution.

Rennie

Igor Kovalenko <kovalenko@attbi.com> wrote:
IK > One well known ‘rule of thumb’ is that for a multithreaded application you
IK > should have one thread per CPU, plus one thread per an outstanding I/O
IK > request, plus one. Based on that, you can come up with a number of ways to
IK > split your application into threads. There are good books on the subject,
IK > reading one of them will be much more helpful than asking for opinions in
IK > newsgroups.

IK > – igor

IK > “RonanK” <ronan.kennelly@nuigalway.ie> wrote in message
IK > news:bg2vbg$l0r$1@inn.qnx.com

Hi,

As I am a new QNX user I would appreciate it if somebody could outline the
circumstances when tasks should be written as a process or when they
IK > should
be written as a thread? I understand the concepts, but as I am designing a
robotic system with many different elements I would like to hear opinions
from the people who know their stuff before I write the different parts as
one or the other and put them all together as a single system.

All opinions appreciated!

RK

My philosophy is that GUI programs are simply that User Interfaces to
some other program that actually does the work. The GUI program should
not be a workhorse itself.

When someone clicks somewhere on the screen the GUI program should send
a message to some API. When some external status changes it should
send a Pulse to the GUI program. The GUI program should then issue
an API status request to the real workhorse program to get the current
status and then update its screen accordingly.

This eliminates the need for the GUI program to be multi-threaded. But
there are MANY other advantages to this approach too. I.E. There
may be more than one Control Interface to some underlying process. And
that control process may be on a remote node.


Bill Caroselli – Q-TPS Consulting
1-(626) 824-7983
qtps@earthlink.net

“Bill Caroselli” <qtps@earthlink.net> wrote in message
news:bh0nn4$m5i$1@inn.qnx.com

My philosophy is that GUI programs are simply that User Interfaces to
some other program that actually does the work. The GUI program should
not be a workhorse itself.

There’s a world of difference between a ‘philosophy’ and a usable GUI
application. Users’ behavior usually does not fit into philosophies that you
want to impose on them. They are unpredictable and irrational. And easily
irritable. Whatever they do, they expect an application to behave in
‘natural’ and ‘intuitive’ way. Having to wait for completion of anything
before they can do something else is the last thing they expect.

When someone clicks somewhere on the screen the GUI program should send
a message to some API. When some external status changes it should
send a Pulse to the GUI program. The GUI program should then issue
an API status request to the real workhorse program to get the current
status and then update its screen accordingly.

This eliminates the need for the GUI program to be multi-threaded.

Great. You send a request that requires long enough time to execute, it
takes too long, user gets annoyed, “damn, i want to cancel that”… oops,
you can’t cancel until you get response back from server because you’re
blocked. Just relax, sit and look at the hourglass… ah, too bad.
Meanwhile, another application popped up (because some external event has
caused it to gain focus, or you just did it yourself out of boredom)…now
you do something with it quickly, it closes (exits or you minimize it) and
guess what? Right, you’ve got yourself a nice (white or otherwise filled
with bogus stuff) rectange underneath the area previously covered by that
app in the middle of your first application’s window… that application is
still executing that damned request so it is blocked and can’t handle the
EXPOSE events (i.e., can’t re-render its own widgets). Ok, maybe you did not
close that second window. Maybe you want to move it around? The ‘trace’ of
rectangles that it will leave will look really artistic…

I have seen way too many crappy GUI applications like that, especially in
QNX. Don’t even want to waste energy arguing…

But
there are MANY other advantages to this approach too. I.E. There
may be more than one Control Interface to some underlying process. And
that control process may be on a remote node.

You’re confusing things. Nobody said anything about a control process.
Whatever that is, and whether it is local or remote, it is irrelevant. The
‘interface’ piece (i.e., the part dealing PURELY with interfacing the user)
by itself needs to be multithreaded if you ever hope to provide any decent
level of user experience. The only other alternative is splitting ‘lenghty’
operations into chunks and handling them one by one, as Photon docs suggest.
Of course that in the end is nothing more than a rather lame
pseudo-multithreading that requires extra work and attention from you and
does not work too well anyway. The only reason they had to come up with a
design marvel like that is that the Photon libs were not thread-safe.

– igor

Ouch! Igor, chill!

Igor Kovalenko <kovalenko@attbi.com> wrote:
IK > “Bill Caroselli” <qtps@earthlink.net> wrote in message
IK > news:bh0nn4$m5i$1@inn.qnx.com

My philosophy is that GUI programs are simply that User Interfaces to
some other program that actually does the work. The GUI program should
not be a workhorse itself.

IK > There’s a world of difference between a ‘philosophy’ and a usable GUI
IK > application. Users’ behavior usually does not fit into philosophies that you
IK > want to impose on them. They are unpredictable and irrational. And easily
IK > irritable. Whatever they do, they expect an application to behave in
IK > ‘natural’ and ‘intuitive’ way. Having to wait for completion of anything
IK > before they can do something else is the last thing they expect.

I completely agree. I don’t know what I said that made you think I
didn’t.

When someone clicks somewhere on the screen the GUI program should send
a message to some API. When some external status changes it should
send a Pulse to the GUI program. The GUI program should then issue
an API status request to the real workhorse program to get the current
status and then update its screen accordingly.

This eliminates the need for the GUI program to be multi-threaded.

IK > Great. You send a request that requires long enough time to execute, it
IK > takes too long, user gets annoyed, “damn, i want to cancel that”… oops,
IK > you can’t cancel until you get response back from server because you’re
IK > blocked. Just relax, sit and look at the hourglass… ah, too bad.
IK > Meanwhile, another application popped up (because some external event has
IK > caused it to gain focus, or you just did it yourself out of boredom)…now
IK > you do something with it quickly, it closes (exits or you minimize it) and
IK > guess what? Right, you’ve got yourself a nice (white or otherwise filled
IK > with bogus stuff) rectange underneath the area previously covered by that
IK > app in the middle of your first application’s window… that application is
IK > still executing that damned request so it is blocked and can’t handle the
IK > EXPOSE events (i.e., can’t re-render its own widgets). Ok, maybe you did not
IK > close that second window. Maybe you want to move it around? The ‘trace’ of
IK > rectangles that it will leave will look really artistic…

IK > I have seen way too many crappy GUI applications like that, especially in
IK > QNX. Don’t even want to waste energy arguing…

OK. I get it. I’m NOT addressing a situation where the user clicks
on a button to send a 100 MB file to some other host and then they
decide they want to CANCLE it. Here you’re probibly neededing/
wanting threads.

The original poster was asking about process control. Robotics, I
think. I was addressing a Real-time Process Control solution.

In all of my designs there is a high priority process that controls whatever. It has an interrupt handler to know the status of hardware and it has one or more threads for processing API requests from clients. Processing an API request for a client is never a matter of:
Receive Request
Do the Request
Reply to the Request
That is NOT REAL-TIME!

The server process is more like:
Receive request (client’s request include a channel to Pulse to)
Validate the requst (is it a valid thing to request)
Reply to the client (OK, I’ll let you know, or Forget about it!)
The server is then able to process the request in a thread all it’s
own. When the request either successfully finishes or fails the
server sends a Pulse to the original client.
The Client sends a Status Query Request to the server.
The server immediately replies with the status, including that the
last request succeded or failed because of “XXXX”.

This is a very real-time approach to process control.

This way the photon program is just sending mouse clicks to the
controlling process via the API and updating the screen when it
receives a Pulse.

But
there are MANY other advantages to this approach too. I.E. There
may be more than one Control Interface to some underlying process. And
that control process may be on a remote node.

IK > You’re confusing things. Nobody said anything about a control process.
IK > Whatever that is, and whether it is local or remote, it is irrelevant. The
IK > ‘interface’ piece (i.e., the part dealing PURELY with interfacing the user)
IK > by itself needs to be multithreaded if you ever hope to provide any decent
IK > level of user experience. The only other alternative is splitting ‘lenghty’
IK > operations into chunks and handling them one by one, as Photon docs suggest.
IK > Of course that in the end is nothing more than a rather lame
IK > pseudo-multithreading that requires extra work and attention from you and
IK > does not work too well anyway. The only reason they had to come up with a
IK > design marvel like that is that the Photon libs were not thread-safe.

Igor Kovalenko <kovalenko@attbi.com> wrote:

Whatever that is, and whether it is local or remote, it is irrelevant. The
‘interface’ piece (i.e., the part dealing PURELY with interfacing the user)
by itself needs to be multithreaded if you ever hope to provide any decent
level of user experience. The only other alternative is splitting ‘lenghty’
operations into chunks and handling them one by one, as Photon docs suggest.
Of course that in the end is nothing more than a rather lame
pseudo-multithreading that requires extra work and attention from you and
does not work too well anyway. The only reason they had to come up with a
design marvel like that is that the Photon libs were not thread-safe.

No, that wasn’t a reason at all. The real reason was that QNX didn’t
have threads at the time.

Besides, splitting the work into little chunks and doing them one at a
time in a workproc is not the only alternative to threads. Calling
PtBkgdHandlerProcess() often enough from various places in your code is
another one. In many cases, it’s no worse than using threads –
especially if the code also wants to update widgets occasionally and
even if you used threads, you’d need to synchronize them anyway to make
sure that the window you’re trying to update hasn’t been closed.