What's the connection between objects and threads?

J

James Kanze

When you say processes do you mean different processes running
and communicating via files\pipelines\sockets and so on?

When I say processes, I mean processes. Note too that I said
"unless the server needs to access shared in memory data". If
that's not the case, there is no need for communication between
the processes once they've been started.
1) Wont it just complicate things?

It depends. Under Unix, child processes inherit open files (and
a socket connection is an "open file" for Unix), so all you
really have to communicate is the file id, and you can
communicate that as a command line argument. (Note that you
*don't* go through system() to do this. You use fork and exec
directly.)
2) Darren is supposed to submit his project to his prof\tester
usually spliting your projects (IMHO) to sub processes gives
it a... (maybe unjustified) scent of a bad design... Most of
my professors were fixed on the notion that an application is
one process.

I'd suggest changing profs in that case---it's actually very,
very exceptional for an application to be a single process.
Especially a server: at the very least, there will be a shell
script which restarts it if it crashes.
(I think that spliting your process to subs is a concept that
is more acknowledged in linux \unix platforms then windows.

That may be because Unix was doing networking and Windows long
before Windows:). The current mode seems to use threads for
everything---you see them when there's really no reason to be
multi-threaded, and you see them when separate processes are a
better solution. In many ways, threads are the worse of the
three solutions, and should only be used if there are strong
reasons why one of the other solutions cannot be used.
AFAIK it's partially due to the reason that in linux you only
load your code once for all the instances of the
application... or something like that... CMIIW!!!)

Actually, it's at least partially because under Unix, most of
the server applications predated threads. FTP and telnet were
around long before Windows even existed. But from a design
standpoint: separate processes are the ultimate encapsulation,
and encapsulation is normally a good thing.
 
S

Szabolcs Ferenczi

They don't, necessarily.

As I have pointed out earlier(!) in this discussion thread,
(http://groups.google.com/group/comp.lang.c++/msg/6413d1c864883be3)
there is no language level notion of a thread in C++ (besides it never
will be, it seems), so in C++ it is true that objects and threads are
not related in any way.

But it is not necessary that objects and threads are not related.

There are computation models as well with co-called active objects. So
it is possible and to an extent it would be natural to combine objects
with threads of computation as he presumed.
 Fundamentally, the "thread" object is
somewhere in the OS, not in your code.

There is no "thread" object there since the thread is not an object
but rather an activity. To be exact we should say "thread of
computation" and mentally one can think about a thread of computation
as a virtual processor with its own program counter. That is it.

Best Regards,
Szabolcs
 
D

darren

Thanks for all of the advice.

1. I'm pretty sure creation of many processes is not allowed. I'll
check though. It seems like creating a process to handle a request is
much more overhead than a thread though.

2. Thats disturbing news about the discouraging comments on
singletons. I wish i had known that before I used so many in my
project already. I have a Logger(), Socket() and UI() singleton
classes, that basically offer static methods to do their job. I
thought the singleton approach was a good idea because I would never
need more than one instance of these things, and this way they can be
accessed from any other object in the program. For example i have a
static Logger::log() that i can use to log a message from any other
object in the code now. I'll look into why the singleton approach is
a bad one, but I wouldn't mind some insight here as well.

As for thread pools, Is the basic idea to create a group of threads,
then have them wait on a condition variable? In my case, when the
server gets a request, it would notify the sleeping threads with a
cond_var, the first thread to then grab the mutex would handle the
request. This approach seems faulty, as only one thread would ever be
able to grab that mutex and run at any given time.
 
J

James Kanze

As I have pointed out earlier(!) in this discussion thread,
(http://groups.google.com/group/comp.lang.c++/msg/6413d1c864883be3)
there is no language level notion of a thread in C++ (besides it never
will be, it seems), so in C++ it is true that objects and threads are
not related in any way.

The next version of the standard will definitely support threads
at the language level; that much has been pretty well proven.
(If nothing else, it's fairly certain that a significant number
of the national bodies will reject it if it doesn't.) That
doesn't mean that objects and threads will necessarily be
related, or that even if they are (e.g. as in boost::threads),
that the way that they are related is relevant to his
application.
But it is not necessary that objects and threads are not related.
There are computation models as well with co-called active objects.

Yes, but they're not really relevant to the way threads are used
in servers.
So it is possible and to an extent it would be natural to
combine objects with threads of computation as he presumed.
There is no "thread" object there since the thread is not an
object but rather an activity.

Within the OS, a thread has state and behavior, so it is an
"object". In some OS's, it may even be implemented as an object
in C++, but regardless of the OS, it's conceptually an object.
(When I wrote a real-time OS, back in 1979, I didn't know what
an "object", in the OO sense was. Never the less, my
processes---which corresponded to what are called threads
today--very definitely were modeled with what we would call an
object today.)
To be exact we should say "thread of computation" and mentally
one can think about a thread of computation as a virtual
processor with its own program counter. That is it.

And shared memory with the other threads in the same process;
that's what separates threads from processes.
 
J

James Kanze

Thanks for all of the advice.
1. I'm pretty sure creation of many processes is not allowed.
I'll check though. It seems like creating a process to handle
a request is much more overhead than a thread though.

That depends on the OS; it often is (but doesn't necessarily
have to be). I suspect that the main reason HTTP servers, like
Apache, use threads instead of processes is performance
considerations, however; HTTP does result in a very large number
of very short lived connections, and maintaining a thread pool
can be a definite performance gain in such cases, at least on
many OS's. IMHO, however, it's an optimization measure: a
compromise of good design forced by performance considerations.

Since you're talking of a school project, and pthreads was
mentionned, it's likely that using processes instead of threads
would defeat the purpose of the exercise. But do be aware that
it's often a preferrable alternative.
2. Thats disturbing news about the discouraging comments on
singletons. I wish i had known that before I used so many in my
project already. I have a Logger(), Socket() and UI() singleton
classes, that basically offer static methods to do their job.

Logging management is a typical example of where a singleton is
usually the best solution. Another example would be
configuration management. On the other hand: each connection
will end up with its own socket, so that definitly cannot be a
singleton, and it's probably preferable to be able to support
multiple user interfaces. Unless the user interface is just the
command line and a configuration file---often the case with
servers, since they are started disconnected from any terminal
(but even then, the may provide a separate socket interface to
connect a manager interface to them).
I thought the singleton approach was a good idea because I
would never need more than one instance of these things,

The question isn't whether you will ever need more than one; the
question is whether by design, there cannot exist more than one.
For example, by definition, you can only have one logging
manager, and only one configuration manager.
and this way they can be accessed from any other object in the
program. For example i have a static Logger::log() that i can
use to log a message from any other object in the code now.
I'll look into why the singleton approach is a bad one, but I
wouldn't mind some insight here as well.

It's not intrinsically bad. It is very overused, however.
As for thread pools, Is the basic idea to create a group of
threads, then have them wait on a condition variable? In my
case, when the server gets a request, it would notify the
sleeping threads with a cond_var, the first thread to then
grab the mutex would handle the request. This approach seems
faulty, as only one thread would ever be able to grab that
mutex and run at any given time.

The thread shouldn't keep the mutex. The usual solution is to
use some sort of a message queue: the connection manager puts a
message with the connection socket id into the message queue,
and the server threads read from it. The mutex is only held
long enough to extract the message from the queue. (It's less
that 20 lines of code, using std::deque for the queue.)
 
I

Ian Collins

Szabolcs said:
Well, he did not point out anything but claimed something. He has
postings that he used to correct the next hour or the next day.

You better read carefully what I have written. I highlighted that one
needs discipline for it.

Discipline or not, the practice is best avoided. Even if the thread is
started in the last (visible) instruction in a constructor, the object
is still not fully constructed until the constructor returns.
 
I

Ian Collins

darren said:
Thanks for all of the advice.

2. Thats disturbing news about the discouraging comments on
singletons. I wish i had known that before I used so many in my
project already. I have a Logger(), Socket() and UI() singleton
classes, that basically offer static methods to do their job.

Do not be misled, these are classic examples where the singleton pattern
is a good solution.
 
S

Szabolcs Ferenczi

...
The next version of the standard will definitely support threads
at the language level; that much has been pretty well proven.

You should know it, since you were trolling in the other discussion
thread in "Threading in new C++ standard" too, that threads are not
going to be included at the language level in C++0x. You were
corrected there by people taking part in C++0x standardisation.
Threading will be included at the library level only. Check out the C+
+0x document proposal and report here if you can find in it any
language elements for defining any computation process at the language
level.
... That
doesn't mean that objects and threads will necessarily be
related,

No, that does not, especially since threads will not appear at the
language level in C++0x. Even if computational processes were included
at the language level, it does not necessarily mean that computational
processes and objects must be related and I have pointed that out
earlier in this discussion! (Please read the posts, do not just troll
into them.)

My claim was that threads of computation and objects can be related.
You claimed wrongly the necessity issue just because you erroneously
think that what you do not know about does not exist.
or that even if they are (e.g. as in boost::threads),
that the way that they are related is relevant to his
application.

Boost is just a wrapper library. It has nothing to do with the
language level nor does it mix objects with threads of computation. It
provides a wrapper for functor objects and the functor is started as a
thread. With respect to threading, Boost is just a wrapper, noting
more.
...

Within the OS, a thread has state and behavior, so it is an
"object".

The thread, i.e. a computation process, is in itself a behaviour and
as such has a state too (remember: virtual processor with its own
program counter). An object, on the other hand, does not have any
behaviour although it has a state. It is a passive entity, a piece of
data and the associated operations defined on it.

Thus a thread of computation is not an object in the sense the term
object is used in the object-oriented programming world. Intermixing
the two is a basic misunderstanding, do not do that.
 In some OS's, it may even be implemented as an object
in C++, but regardless of the OS, it's conceptually an object.

Conceptually it is not an object but a virtual processor.
...

And shared memory with the other threads in the same process;
that's what separates threads from processes.

It depends on the terminology what you call a process, task, thread,
light weight process, heavy weight process, however, as far as we
discuss the nature of the computational process as opposed to the
objects, these terminological issues are all irrelevant.

Best Regards,
Szabolcs
 
S

Szabolcs Ferenczi

Discipline or not, the practice is best avoided.

Discipline always helps.---Discipline hurts the hackers though.
 Even if the thread is
started in the last (visible) instruction in a constructor, the object
is still not fully constructed until the constructor returns.

And the constructor does return. And the object is fully constructed.
And discipline always help.

Please read back what I suggested exactly.

Thanks for your efforts.

Best Regards,
Szabolcs
 
I

Ian Collins

Szabolcs said:
Discipline always helps.---Discipline hurts the hackers though.


And the constructor does return. And the object is fully constructed.
And discipline always help.

Please read back what I suggested exactly.
There's nothing in what you wrote that stops the thread from running
before the constructor returns.
 
S

Szabolcs Ferenczi

There's nothing in what you wrote that stops the thread from running
before the constructor returns.

Right. And now please read carefully what I have written in this
thread about this issue.

Best Regards,
Szabolcs
 
I

Ian Collins

Szabolcs said:
Right. And now please read carefully what I have written in this
thread about this issue.
I haven't seen anything of any substance. Just in case the pertinent
message didn't reach my server, please repost the relevant text.
 
I

Ian Collins

darren said:
hi Chris. Thanks for the reply and the sample code. I'll have to
spend some time understanding it. For starters why do you have this
ection:


I've never seen code like this. are the parameters taking pointers to
a class??? it seems like thread_create is declared twoice, once as
friend and once not...
Note the first declaration is extern "C". You can't declare a friend as
extern "C" in once declaration, so you have to forward declare it first.
I've also never seen extern C before, i'll have to look up what that
is.
Most thread APIs are written in C. So you must pass them a C linkage
function for the thread entry point. Some compilers will accept a C++
linkage function without complaint, while others (correctly) issue a
diagnostic.
 
S

Szabolcs Ferenczi

I haven't seen anything of any substance.  Just in case the pertinent
message didn't reach my server, please repost the relevant text.

I am afraid you did not read carefully but here you go:

"It looks like you have the approach in mind where the objects are
data structures (passive elements) and the threads of computation
(active elements) are orthogonal to each other. In this case you could
keep them separate and do not intermix them, it would not be a good
idea."
http://groups.google.com/group/comp.lang.c++/msg/6413d1c864883be3

"There are programming models where there are objects which are active
entities. As I earlier mentioned one early proposal of this kind is
the Distributed Processes programming concept. This means that it
depends on discipline only. You can build an abstraction for yourself
where the object starts its dedicated thread as the last step in the
constructor and joins the low level thread in the destructor. That is
not a bad idea at all."
http://groups.google.com/group/comp.lang.c++/msg/250fdce805e9f407

And now, please try to demonstrate what problem you can foresee and
why that cannot be avoided by disciplined work. Please provide
evidences and examples.

I am looking forward to your demonstration.

Best Regards,
Szabolcs

P.S. It might be a good idea if you open a new discussion thread for
this issue.
 
I

Ian Collins

Szabolcs said:
I am afraid you did not read carefully but here you go:

"There are programming models where there are objects which are active
entities. As I earlier mentioned one early proposal of this kind is
the Distributed Processes programming concept. This means that it
depends on discipline only. You can build an abstraction for yourself
where the object starts its dedicated thread as the last step in the
constructor and joins the low level thread in the destructor. That is
not a bad idea at all."

So I was right, there was nothing of any substance.
And now, please try to demonstrate what problem you can foresee and
why that cannot be avoided by disciplined work. Please provide
evidences and examples.
You still have not addressed the fundamental issue of the new thread
using an object that has not been fully constructed. Please provide
example code that solves this problem.
 
S

Szabolcs Ferenczi

So I was right, there was nothing of any substance.




You still have not addressed the fundamental issue of the new thread
using an object that has not been fully constructed.  Please provide
example code that solves this problem.

I have fulfilled your request. I have also asked you to do the
demonstration about the problem you foresee. It is fair if you do that
before you try to push me, isn't it.

I am looking forward to your demonstration.

Best Regards,
Szabolcs

P.S. I have a feeling that you will escape not do that for some
strange reason.
 
G

Gianni Mariani

Ian Collins wrote:
....
You still have not addressed the fundamental issue of the new thread
using an object that has not been fully constructed. Please provide
example code that solves this problem.

Almost all threaded code I have seen that works in a cross platform is
susceptible to the "problem" in a strict sense.

In practice, if the thread is "enabled" as the very last thing in the
most derived constructor, then there it is very unlikely you're ever
going to see a problem.

I have yet to find an alternative that is acceptably straight forward as
this approach.
 
I

Ian Collins

Szabolcs said:
I have fulfilled your request.

I'm afraid you have not. At no point have you shown how to avoid the
new thread running before the object is constructed.
I have also asked you to do the
demonstration about the problem you foresee. It is fair if you do that
before you try to push me, isn't it.
The onus isn't on me, what you propose introduced undefined behaviour
(using an incomplete object). You claimed this problem can be avoided
through discipline. A small code example is required to demonstrate that.
 
I

Ian Collins

Gianni said:
Ian Collins wrote:
....

Almost all threaded code I have seen that works in a cross platform is
susceptible to the "problem" in a strict sense.

In practice, if the thread is "enabled" as the very last thing in the
most derived constructor, then there it is very unlikely you're ever
going to see a problem.
The problem is the thread class tends to be used as a base, so this
strict rule breaks down.
I have yet to find an alternative that is acceptably straight forward as
this approach.
I guess I was bitten by it too often in my formative years and moved to
the functor style now adopted by boost. Now I find the boost style much
more straight forward and less fragile. The object used for the thread
is always complete and in a known state.
 
S

Szabolcs Ferenczi

I'm afraid you have not.  At no point have you shown how to avoid the
new thread running before the object is constructed.


The onus isn't on me,

If you want to be fair then yes, it is your turn. You claimed
something and now you should prove that. You claimed that given the
object launches a thread as the last step in the construction
procedure, it would result in some data race. Please demonstrate what
do you mean. What data race?
what you propose introduced undefined behaviour
(using an incomplete object).

That should you demonstrate it somehow. I am curious. I predicted you
would fail and now you are proving that instead.
 You claimed this problem can be avoided
through discipline.  A small code example is required to demonstrate that.

What problem? Please give example. It is your turn but I can see you
are escaping instead. Very brave indeed.

Go ahead, I am ready to learn.

I am looking forward to your demonstration.

Best Regards,
Szabolcs
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top