Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What's the connection between objects and threads?

21 views
Skip to first unread message

darren

unread,
May 17, 2008, 4:20:11 PM5/17/08
to
Hi

I have to write a multi-threaded program. I decided to take an OO
approach to it. I had the idea to wrap up all of the thread functions
in a mix-in class called Threadable. Then when an object should run
in its own thread, it should implement this mix-in class. Does this
sound like plausible design decision?

I'm surprised that C++ doesn't have such functionality, say in its
STL. This absence of a thread/object relationship in C++ leads me to
believe that my idea isn't a very good one.

I would appreciate your insights. thanks

Gianni Mariani

unread,
May 17, 2008, 4:54:24 PM5/17/08
to

The next revision of the C++ standard does in fact have thread support.

The threading concepts in the next revision will probably work with what
you describe but there is a few newer concepts - one is called a "future".

In the meantime, there are some alternative libraries - boost implements
many of the standard's new features already as well as other like
commonc++ and Austria c++ also have cross platform threading support for
C++.

In most of my newer projects, I use thread pools which is very different
to threads.

Paavo Helde

unread,
May 17, 2008, 4:58:33 PM5/17/08
to
darren <mino...@gmail.com> wrote in news:7083eb1a-4dbd-4b94-866b-
fddab7...@c19g2000prf.googlegroups.com:

The current semi-official solution for threading in C++ is boost::thread
library. From what I've heard the C++0x standard will also be based on
that.

In boost::thread one has a functor object, which is copied over to the
started thread and then executed. Each functor object has its own thread
function. I see no point for any Threadable base class or "interface".

In principle, no object does run in any thread. Only the objects' methods
might run in some thread or another, depending on which thread they are
called. There are at least two useful types of objects:

- single-threaded objects, whose methods may not run in parallel by
different threads. This is best ensured by that the pointer(s) to the
object are visible only to a single thread at a time; passing the object
to another thread is possible by ensuring there are no pointers left to
the object or its inners in the current owner thread.

- multi-threaded objects, whose all public methods can be called from any
thread at any time. Typically objects of this kind perform internal
locking when accessing their private data.

hth
Paavo

Szabolcs Ferenczi

unread,
May 17, 2008, 6:56:47 PM5/17/08
to
On May 17, 10:20 pm, darren <minof...@gmail.com> wrote:

"What's the connection between objects and threads?"

Good question. In C++ there is no connection between objects and
threads since there are no threads in C++.

C++ does not have the notion of the process or the thread of
computation at the language level. On the other hand, C++ does have
the notion of the object at the language level. It is an object-
oriented programming language but not a concurrent object-oriented
one. The bad news is that it is not going to be one either.

The good news is that you can introduce threads of computation into a C
++ program via some libraries. The coming C++0x would even include
such a library, though.

So, you can take any concurrency libraries to mix threads into an
object-oriented program in C++. Objects and threads of computation are
usually orthogonal to each other. Objects are (passive) data
structures and, on the other hand, threads of computation are rather
activities with their own program counters in your program.

You can keep them separate as was done in the first class-based
concurrent programming language, Concurrent Pascal, or you can combine
them together as was done, for instance, in an early language proposal
called Distributed Processes (DP).

> I had the idea to wrap up all of the thread functions
> in a mix-in class called Threadable."

What do you mean by "thread functions"?

> Does this
> sound like plausible design decision?

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.
Although, if you must use any lower level library (such as Pthread),
it is a good idea to build your own higher level abstractions, I
think.

In this case it is very important to make a difference between the
objects which are meant to be used exclusively from one thread of
computation only and between the objects which are to be shared among
many threads. The shared objects must be protected so that they could
be accessed by the threads in a mutually exclusive way only (see the
Monitor concept).

Best Regards,
Szabolcs

darren

unread,
May 17, 2008, 8:24:49 PM5/17/08
to
Thanks for the responses everybody.

I have actually heard of Boost. I saw it in another post on this user
group about threads. My dilemma is that for this project, we were
specifically told that we must use the pthread library and our
deliverable must only be source code and a Makefile.

Doest Boost use pthread library calls in its implementation, or are
they up to something else? Maybe I'll email my prof and ask if using
Boost is permitted.

As for my current idea:

I planned to write a class called myThreads which would wrap up calls
to the pthread library, like pthread_create. Then anytime i need a
thread I'll instantiate one of these objects. I was thinking that in
one of these 'myThread" constructors, a new thread would be created
and ran. Again, i'm new to thread programming, so i dont know if this
will work or not.

there was also mention about threadpools. Our instructor said this may
be a good way to implement our project. How are they significantly
different than concepts of thread programming (as somebody here
mentioned they were).

thanks again.

Chris Thomasson

unread,
May 17, 2008, 11:35:48 PM5/17/08
to
"darren" <mino...@gmail.com> wrote in message
news:3e1c2116-118e-4a9a...@d19g2000prm.googlegroups.com...

> Thanks for the responses everybody.
>
> I have actually heard of Boost. I saw it in another post on this user
> group about threads. My dilemma is that for this project, we were
> specifically told that we must use the pthread library and our
> deliverable must only be source code and a Makefile.
>
> Doest Boost use pthread library calls in its implementation, or are
> they up to something else? Maybe I'll email my prof and ask if using
> Boost is permitted.
>
> As for my current idea:
>
> I planned to write a class called myThreads which would wrap up calls
> to the pthread library, like pthread_create. Then anytime i need a
> thread I'll instantiate one of these objects. I was thinking that in
> one of these 'myThread" constructors, a new thread would be created
> and ran. Again, i'm new to thread programming, so i dont know if this
> will work or not.
[...]

You don't generally want to create threads in constructors because of a
possible race-condition. Think of starting a thread in an object's
constructor which starts to run and operate on it _before_ its ctor has
finished... Anyway:

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/b9b2ce54349af0f
(please read all!)


Here is some very simple source-code that might help you:
____________________________________________________________________

/* VERY Simple Thread Library Code
______________________________________________________________*/
#include <pthread.h>

class thread_base;
extern "C" void* thread_base_entry(void*);
static void thread_create(thread_base* const);
static void thread_join(thread_base* const);

class thread_base {
pthread_t m_id;
friend void* thread_base_entry(void*);
friend void thread_create(thread_base* const);
friend void thread_join(thread_base* const);
virtual void on_thread_entry() = 0;
public:
virtual ~thread_base() throw() = 0;
};


thread_base::~thread_base() throw() {}

void* thread_base_entry(void* state) {
reinterpret_cast<thread_base*>(state)->on_thread_entry();
return 0;
}


void thread_create(thread_base* const _this) {
int const status = pthread_create(&_this->m_id, NULL,
thread_base_entry, _this);
if (status) {
throw int(status);
}
}


void thread_join(thread_base* const _this) {
int const status = pthread_join(_this->m_id, NULL);
if (status) {
throw int(status);
}
}


/* Very Simple Application Code
______________________________________________________________*/
#include <cstdio>

class my_thread : public thread_base {
public:
my_thread() {
std::printf("(%p)-my_thread::my_thread()\n",
reinterpret_cast<void*>(this));
}

~my_thread() throw() {
std::printf("(%p)-my_thread::~my_thread() throw()\n",
reinterpret_cast<void*>(this));
}

private:
void on_thread_entry() {
std::printf("void (%p)-my_thread::on_thread_entry()\n",
reinterpret_cast<void*>(this));
}
};


#define RUN_DEPTH() 10
#define THREAD_DEPTH() 32
int main() {
int runs = 0;
for (; runs < RUN_DEPTH(); ++runs) {
int i = 0;
my_thread threads[THREAD_DEPTH()];

try {
for (; i < THREAD_DEPTH(); ++i) {
thread_create(&threads[i]);
}
} catch (int const& e) {
std::printf("thread_create throws status %d!\n", e);
}

for (--i; i > -1; --i) {
try {
thread_join(&threads[i]);
} catch (int const& e) {
std::printf("thread_join throws status %d!\n", e);
}
}
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
std::puts("\n\n____________________________________________\n\
Press <ENTER> to exit...");
std::getchar();
return 0;
}

____________________________________________________________________

Any questions?

darren

unread,
May 18, 2008, 4:10:45 AM5/18/08
to
On May 17, 8:35 pm, "Chris Thomasson" <cris...@comcast.net> wrote:
> "darren" <minof...@gmail.com> wrote in message

>
> news:3e1c2116-118e-4a9a...@d19g2000prm.googlegroups.com...
>
> > Thanks for the responses everybody.
>
> > I have actually heard of Boost. I saw it in another post on this user
> > group about threads. My dilemma is that for this project, we were
> > specifically told that we must use the pthread library and our
> > deliverable must only be source code and a Makefile.
>
> > Doest Boost use pthread library calls in its implementation, or are
> > they up to something else? Maybe I'll email my prof and ask if using
> > Boost is permitted.
>
> > As for my current idea:
>
> > I planned to write a class called myThreads which would wrap up calls
> > to the pthread library, like pthread_create. Then anytime i need a
> > thread I'll instantiate one of these objects. I was thinking that in
> > one of these 'myThread" constructors, a new thread would be created
> > and ran. Again, i'm new to thread programming, so i dont know if this
> > will work or not.
>
> [...]
>
> You don't generally want to create threads in constructors because of a
> possible race-condition. Think of starting a thread in an object's
> constructor which starts to run and operate on it _before_ its ctor has
> finished... Anyway:
>
> http://groups.google.com/group/comp.programming.threads/browse_frm/th...

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:

> class thread_base;
> extern "C" void* thread_base_entry(void*);
> static void thread_create(thread_base* const);
> static void thread_join(thread_base* const);

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...

I've also never seen extern C before, i'll have to look up what that
is.

thanks again.

ManicQin

unread,
May 18, 2008, 4:13:17 AM5/18/08
to

At the company that I'm working we work the way you suggested
(which could be imply that YOU DONT WANT TO USE IT! ;) )
but it works fine and most of the times it's transparent.

My problem with thread pools (and I'll be happy if someone contradicts
me)
is that until .Net did'nt introduce thread pools I have'nt heared
about it
and it makes me worried that maybe it's a bit platform specific.
(But if you dont care than it's great method to ease your work)

If you could shed some light on your project maybe people could
give a more precise counsel on the MT method you should use...

darren

unread,
May 18, 2008, 5:43:24 AM5/18/08
to

Its a multithreaded web server using pthreads and the socket api (hey
everybody else in my class looking for ideas :) ).

Here's my basic algorithm:
1. main() makes a singleton ServerKernal object to control program
flow
2. ServerKernal listens for requests on a specified port. this is done
by creating a thread that loops and continuously accepts connections.
3. A successful accepted connection is put into a queue (from the STL
library).
4. Meanwhile, back at the ranch, another thread is created and running
that continuously checks for entries into the queue.
5. if an entry is in there, a new thread is spawned to handle the
request. That thread then dies.

What do you think of this algorithm?

A couple of things i'm thinking about:
1. As per the reason i created this post, I was thinking about how
objects related to threads. At first I was thinking that an object
should create a thread. this has been advised as bad (thanks for the
advice!). Now I'm thinking that instead, threads should create
objects, and destroy them before the thread ends. for example, when a
request is in the queue, a thread is created to handle it. Within this
new thread, a RequestHandler object is instantiated. It's methods are
used to process the request. The object is then destroyed. Finally,
the thread ends.

2 I was thinking about thread pools. Maybe there could be 10 threads
set up, waiting for requests. I dont know much about thread pools yet
though. It may not be appropriate. Or, maybe the threads could be
sleeping, then awoken by signaling when a request enters the queue.

Szabolcs Ferenczi

unread,
May 18, 2008, 6:44:11 AM5/18/08
to
On May 18, 11:43 am, darren <minof...@gmail.com> wrote:

> At first I was thinking that an object
> should create a thread.  this has been advised as bad (thanks for the
> advice!).  

That is not a bad idea at all that an object creates a thread in the
constructor. Do not be mistaken.

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.

That means that you can use configurator blocks in your program where
you declare so-called thread objects and shared objects together.

{
Buffer b;
Producer p(b);
Consumer c(b);
}

The block realises a parallel block or fork-join block as they call it
in a trendy terminology.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 18, 2008, 6:49:38 AM5/18/08
to
On May 18, 11:43 am, darren <minof...@gmail.com> wrote:

> Here's my basic algorithm:
> 1. main() makes a singleton ServerKernal object to control program
> flow

> What do you think of this algorithm?

Try to avoid using singletons (if you refer to the singleton pattern).
It is not a good idea even in non-MT programs. You can always avoid
using singletons by disciplined programming. In this case you do not
need singleton either.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 18, 2008, 7:12:27 AM5/18/08
to
On May 18, 2:24 am, darren <minof...@gmail.com> wrote:

> Doest Boost use pthread library calls in its implementation, or are
> they up to something else?  

As far as I know, Boost is built on Pthread library on the Unix
platform. In principle it could be implemented on any other low level
libraries as well on Unix too. That is the benefit of higher level
structures that they hide low level details.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 18, 2008, 7:22:26 AM5/18/08
to
On May 18, 11:43 am, darren <minof...@gmail.com> wrote:

> 3. A successful accepted connection is put into a queue (from the STL
> library).
> 4. Meanwhile, back at the ranch, another thread is created and running
> that continuously checks for entries into the queue.

Be aware that although STL is thread-safe to a certain extent, you
must wrap around the STL data structure to make a kind of a bounded
buffer out of it.

The point is that checking the data structure and carrying out the
corresponding action must be atomic. For instance checking if there is
element in the data structure and taking that element must be atomic.

Best Regards,
Szabolcs

ManicQin

unread,
May 18, 2008, 7:29:20 AM5/18/08
to
On May 18, 12:43 pm, darren <minof...@gmail.com> wrote:

> A couple of things i'm thinking about:
> 1. As per the reason i created this post, I was thinking about how
> objects related to threads. At first I was thinking that an object
> should create a thread. this has been advised as bad (thanks for the
> advice!). Now I'm thinking that instead, threads should create
> objects, and destroy them before the thread ends. for example, when a
> request is in the queue, a thread is created to handle it. Within this
> new thread, a RequestHandler object is instantiated. It's methods are
> used to process the request. The object is then destroyed. Finally,
> the thread ends.
>
> 2 I was thinking about thread pools. Maybe there could be 10 threads
> set up, waiting for requests. I dont know much about thread pools yet
> though. It may not be appropriate. Or, maybe the threads could be
> sleeping, then awoken by signaling when a request enters the queue.


1. sounds good maybe you would like to read about RAII
(or auto_ptr in stl - remeber not to create a continer of auto_ptrs!)

2. use thread pools. it's easy and it's a "fire and forget"
mechanizm...


Szabolcs Ferenczi wrote:

> Try to avoid using singletons (if you refer to the singleton pattern).
> It is not a good idea even in non-MT programs. You can always avoid
> using singletons by disciplined programming. In this case you do not
> need singleton either.

He is right but! The fact that "sigletons are evil" (google it) is not
always a common knowledge.
If you've learned singleton you are being expected to use it and
reciting to you prof\tester why you decided to avoid using singletons
will not always be accepted.

Szabolcs Ferenczi

unread,
May 18, 2008, 7:30:10 AM5/18/08
to
On May 18, 11:43 am, darren <minof...@gmail.com> wrote:

> 5. if an entry is in there, a new thread is spawned to handle the
> request. That thread then dies.

If you make the shared data structure thread safe so that multiple
threads can get element from it, you do not have to create and destroy
the thread but you can launch a certain number of worker threads that
compete to obtain a work packets from the queue. This is a simple
solution. If you want to tune it dynamically according to the work
load, a thread pool can be set up.

Best Regards,
Szabolcs

James Kanze

unread,
May 18, 2008, 9:23:35 AM5/18/08
to
On 18 mai, 12:44, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

> On May 18, 11:43 am, darren <minof...@gmail.com> wrote:

> > At first I was thinking that an object should create a
> > thread. this has been advised as bad (thanks for the
> > advice!).

> That is not a bad idea at all that an object creates a thread
> in the constructor. Do not be mistaken.

Except that, as Chris has already pointed out, it results in a
race condition. It's a serious design error.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

unread,
May 18, 2008, 9:27:52 AM5/18/08
to
On 18 mai, 13:29, ManicQin <Manic...@gmail.com> wrote:
> On May 18, 12:43 pm, darren <minof...@gmail.com> wrote:

[...]


> > Try to avoid using singletons (if you refer to the singleton pattern).
> > It is not a good idea even in non-MT programs. You can always avoid
> > using singletons by disciplined programming. In this case you do not
> > need singleton either.

> He is right

Bullshit. (If you read any of Szabolcs' postings, you'll
quickly realize that he's never actually written any real code.)
You don't want to abuse them, but there are special cases where
they are the appropriate solution. In the case of detached
threads, in fact, some form of singleton is almost necessary for
a clean shutdown.

Szabolcs Ferenczi

unread,
May 18, 2008, 9:40:42 AM5/18/08
to
On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:

> Except that, as Chris has already pointed out, it results in a
> race condition.  It's a serious design error.

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. It is hopless for you but at least you calm
down.

I hope I could help though.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 18, 2008, 9:43:49 AM5/18/08
to
On May 18, 3:27 pm, James Kanze <james.ka...@gmail.com> wrote:
> On 18 mai, 13:29, ManicQin <Manic...@gmail.com> wrote:
>
> > On May 18, 12:43 pm, darren <minof...@gmail.com> wrote:
>
>     [...]
>
> > > Try to avoid using singletons (if you refer to the singleton pattern).
> > > It is not a good idea even in non-MT programs. You can always avoid
> > > using singletons by disciplined programming. In this case you do not
> > > need singleton either.
> > He is right
>
> Bullshit.  (If you read any of Szabolcs' postings, you'll
> quickly realize that he's never actually written any real code.)
> You don't want to abuse them, but there are special cases where
> they are the appropriate solution.  In the case of detached
> threads, in fact, some form of singleton is almost necessary for
> a clean shutdown.

Calm down, my friend, and do not write "Bullshit".

If you do not know about something, do not attack it just because of
your ignorance.

The singleton pattern is discouraged even by its creator.

Best Regards,
Szabolcs

James Kanze

unread,
May 18, 2008, 9:56:47 AM5/18/08
to
On 18 mai, 11:43, darren <minof...@gmail.com> wrote:
> On May 18, 1:13 am, ManicQin <Manic...@gmail.com> wrote:

[...]


> > If you could shed some light on your project maybe people
> > could give a more precise counsel on the MT method you
> > should use...

> Its a multithreaded web server using pthreads and the socket
> api (hey everybody else in my class looking for ideas :) ).

> Here's my basic algorithm:
> 1. main() makes a singleton ServerKernal object to control program
> flow
> 2. ServerKernal listens for requests on a specified port. this is done
> by creating a thread that loops and continuously accepts connections.

There's really not necessarily a reason to start a separate
thread for this.

> 3. A successful accepted connection is put into a queue (from the STL
> library).
> 4. Meanwhile, back at the ranch, another thread is created and running
> that continuously checks for entries into the queue.
> 5. if an entry is in there, a new thread is spawned to handle the
> request. That thread then dies.

That sounds like extra complication as well. What's wrong with
just starting the connection thread immediately when you get the
connection?

> What do you think of this algorithm?

What are the constraints concerning shutdown? If you don't have
any (i.e. the only way to stop the process is to kill it), then
your connection threads are basically fire and forget: you don't
really need to keep any trace of them (which means that you
don't have any "thread" objects). In fact, unless the server
needs to access shared in memory data, it may be preferable to
use processes instead of threads. (That's what a lot of
traditional servers do: FTP, telnet, etc.)

> A couple of things i'm thinking about:
> 1. As per the reason i created this post, I was thinking about how
> objects related to threads.

They don't, necessarily. Fundamentally, the "thread" object is
somewhere in the OS, not in your code. If the thread should do
something resulting in returned data, and you will eventually
have to wait for it (join), then some sort of object is probably
desirable in your application. This object is traditionally
called a "thread" as well, but it's important to realize that it
isn't really the thread itself, it's just an interface to
certain characteristics of the thread the OS is maintaining. If
you need to support clean shutdown, then you'll need some means
of keeping track of which threads are active (which might result
in "thread" objects as well), so that you can notify them of a
desired shutdown, and wait until all of them have shutdown. But
in the simplest case of a server, it's fire and forget for each
connection. Just start the thread, and forget about it; the
thread takes care of everything itself. (Conceptually, you
might think of it as an object, and within the OS, it certainly
is, but practically, in your code, at least with pthreads or
WinThreads, it's a function with its own stack, and that's it.)

> At first I was thinking that an object should create a thread.
> this has been advised as bad (thanks for the advice!).

In the end, it is the call to pthread_create which will create
the thread. Depending on what you want to do with it, you might
want to create an object which manages this information. The
type of this object should not be a base class, nor should
instances be members of another object. Practically, doing so
leads to race conditions; conceptually, you're modeling
something in the OS backwards from the way the OS implements it:
in the OS, it is the thread which owns the functions it is
executing, and not vice versa---in other words, the "object"
which you execute is a member or base class of the thread, and
not vice versa. In C++, supposing you need a thread object, you
can do this in three ways: the type of the thread object can be a
template on the object to be executed, it can take over
ownership of an object create elsewhere, or it can make a copy
of an object you pass its constructor. The latter is what
Boost does, but it requires some pretty tricky template
programming (not in Boost threads, but in Boost functions, which
Boost threads uses) to work. The second solution is probably
the easiest for a beginner to implement; you define an abstract
base class Threadable or Runnable, with an pure virtual
function run, and you pass a pointer to this to your thread
object.

> Now I'm thinking that instead, threads should create objects,
> and destroy them before the thread ends.

Almost certainly. And each thread has its own stack on which it
can do this.

> for example, when a request is in the queue, a thread is
> created to handle it. Within this new thread, a
> RequestHandler object is instantiated. It's methods are used
> to process the request. The object is then destroyed.
> Finally, the thread ends.

> 2 I was thinking about thread pools. Maybe there could be 10
> threads set up, waiting for requests. I dont know much about
> thread pools yet though. It may not be appropriate. Or, maybe
> the threads could be sleeping, then awoken by signaling when a
> request enters the queue.

The usual way to use thread pools is for all of the threads to
wait on a message queue. The listener thread then sends the
incoming request to the queue; depending on design constraints,
it may decide to create an additional new thread first, if no
thread is currently waiting, or to reject the connection, if no
thread picks up the message after a specified time.

James Kanze

unread,
May 18, 2008, 9:56:58 AM5/18/08
to

ManicQin

unread,
May 18, 2008, 11:06:20 AM5/18/08
to
On May 18, 4:56 pm, James Kanze <james.ka...@gmail.com> wrote:

> What are the constraints concerning shutdown? If you don't have
> any (i.e. the only way to stop the process is to kill it), then
> your connection threads are basically fire and forget: you don't
> really need to keep any trace of them (which means that you
> don't have any "thread" objects). In fact, unless the server
> needs to access shared in memory data, it may be preferable to
> use processes instead of threads. (That's what a lot of
> traditional servers do: FTP, telnet, etc.)


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

1) Wont it just complicate things?
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 think that
spliting
your process to subs is a concept that is more acknowledged in linux
\unix platforms then
windows. 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!!!)

James Kanze

unread,
May 18, 2008, 12:04:25 PM5/18/08
to
On 18 mai, 17:06, ManicQin <Manic...@gmail.com> wrote:
> On May 18, 4:56 pm, James Kanze <james.ka...@gmail.com> wrote:

> > What are the constraints concerning shutdown? If you don't have
> > any (i.e. the only way to stop the process is to kill it), then
> > your connection threads are basically fire and forget: you don't
> > really need to keep any trace of them (which means that you
> > don't have any "thread" objects). In fact, unless the server
> > needs to access shared in memory data, it may be preferable to
> > use processes instead of threads. (That's what a lot of
> > traditional servers do: FTP, telnet, etc.)

> 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.

Szabolcs Ferenczi

unread,
May 18, 2008, 12:22:29 PM5/18/08
to
On May 18, 3:56 pm, James Kanze <james.ka...@gmail.com> wrote:
> On 18 mai, 11:43, darren <minof...@gmail.com> wrote:

> > A couple of things i'm thinking about:
> > 1. As per the reason i created this post, I was thinking about how
> > objects related to threads.
>
> 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

darren

unread,
May 18, 2008, 3:08:20 PM5/18/08
to
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.

James Kanze

unread,
May 18, 2008, 3:59:34 PM5/18/08
to
On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

> On May 18, 3:56 pm, James Kanze <james.ka...@gmail.com> wrote:

> > On 18 mai, 11:43, darren <minof...@gmail.com> wrote:
> > > A couple of things i'm thinking about:
> > > 1. As per the reason i created this post, I was thinking about how
> > > objects related to threads.

> > 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.

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.

> > 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.

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.

James Kanze

unread,
May 18, 2008, 4:11:41 PM5/18/08
to
On 18 mai, 21:08, darren <minof...@gmail.com> wrote:
> 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.)

Ian Collins

unread,
May 18, 2008, 4:41:16 PM5/18/08
to
Szabolcs Ferenczi wrote:
> On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:
>
>> Except that, as Chris has already pointed out, it results in a
>> race condition. It's a serious design error.
>
> 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.

--
Ian Collins.

Ian Collins

unread,
May 18, 2008, 4:47:24 PM5/18/08
to
darren wrote:
> 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.

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 5:00:08 PM5/18/08
to
On May 18, 9:59 pm, James Kanze <james.ka...@gmail.com> wrote:
> On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> wrote:
>
> > On May 18, 3:56 pm, James Kanze <james.ka...@gmail.com> wrote:
> ...

> 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.

> ...


> > > 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.
>
> 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.

> ...


> > 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.

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

Szabolcs Ferenczi

unread,
May 18, 2008, 5:12:34 PM5/18/08
to
On May 18, 10:41 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> Szabolcs Ferenczi wrote:
> > On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:
>
> >> Except that, as Chris has already pointed out, it results in a
> >> race condition.  It's a serious design error.
>
> > 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.

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

Ian Collins

unread,
May 18, 2008, 5:24:35 PM5/18/08
to
Szabolcs Ferenczi wrote:
> On May 18, 10:41 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> Szabolcs Ferenczi wrote:
>>> On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:
>>>> Except that, as Chris has already pointed out, it results in a
>>>> race condition. It's a serious design error.
>>> 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.
>
> 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.
>
There's nothing in what you wrote that stops the thread from running
before the constructor returns.

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 5:40:29 PM5/18/08
to

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

Best Regards,
Szabolcs

Ian Collins

unread,
May 18, 2008, 5:58:36 PM5/18/08
to
I haven't seen anything of any substance. Just in case the pertinent
message didn't reach my server, please repost the relevant text.

--
Ian Collins.

Ian Collins

unread,
May 18, 2008, 6:03:56 PM5/18/08
to
darren wrote:
> On May 17, 8:35 pm, "Chris Thomasson" <cris...@comcast.net> wrote:
>
> 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:
>
>> class thread_base;
>> extern "C" void* thread_base_entry(void*);
>> static void thread_create(thread_base* const);
>> static void thread_join(thread_base* const);
>
> 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.

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 6:12:24 PM5/18/08
to

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.

Ian Collins

unread,
May 18, 2008, 6:19:55 PM5/18/08
to
Szabolcs Ferenczi wrote:
> On May 18, 11:58 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> Szabolcs Ferenczi wrote:
>>> On May 18, 11:24 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>>>> 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.
>> 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:
>
> "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.

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 6:26:55 PM5/18/08
to

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.

Gianni Mariani

unread,
May 18, 2008, 6:38:07 PM5/18/08
to
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.


Ian Collins

unread,
May 18, 2008, 6:48:41 PM5/18/08
to
Szabolcs Ferenczi wrote:
> On May 19, 12:19 am, Ian Collins <ian-n...@hotmail.com> 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.
>
> 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.

--
Ian Collins.

Ian Collins

unread,
May 18, 2008, 6:58:55 PM5/18/08
to
Gianni Mariani wrote:
> 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.
>
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.

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 7:05:44 PM5/18/08
to
On May 19, 12:48 am, Ian Collins <ian-n...@hotmail.com> wrote:
> Szabolcs Ferenczi wrote:
> > On May 19, 12:19 am, Ian Collins <ian-n...@hotmail.com> 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.
>
> > 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,

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.

Ian Collins

unread,
May 18, 2008, 7:25:16 PM5/18/08
to
Szabolcs Ferenczi wrote:
>
> 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?
>
I made no such claim.

All I claim is that launching a thread in a constructor invokes
undefined behaviour. Nothing more, nothing less.

You countered with "And the constructor does return. And the object is
fully constructed.". The new thread could run to completion before the
constructor returned, or the constructor could return before the thread
runs. Either is possible and neither is the specified scenario, because
there isn't one.

Do you deny using an incomplete object doesn't invoke undefined behaviour?

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 7:35:40 PM5/18/08
to
On May 19, 12:48 am, Ian Collins <ian-n...@hotmail.com> wrote:
> Szabolcs Ferenczi wrote:
> > On May 19, 12:19 am, Ian Collins <ian-n...@hotmail.com> 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.
>
> > I have fulfilled your request.
>
> I'm afraid you have not.

Oh yes, I have. I have copied the fragments here that you cannot
understand still.

> At no point have you shown how to avoid the
> new thread running before the object is constructed.

I never wanted to show you anything like that. I even agreed to you
that the thread can start running before the constructor is completed.
I cannot see any poblem with that.

You said you have some problem with that.

What is your problem exactly? It would be good, if instead of trolling
you would prove something finally.

Best Regards,
Szabolcs

Ian Collins

unread,
May 18, 2008, 7:41:04 PM5/18/08
to
Szabolcs Ferenczi wrote:
>
> What is your problem exactly? It would be good, if instead of trolling
> you would prove something finally.
>
I see your true colours have finally come through, insult all who
disagree with you.

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 18, 2008, 7:58:49 PM5/18/08
to
On May 19, 1:25 am, Ian Collins <ian-n...@hotmail.com> wrote:
> Szabolcs Ferenczi wrote:
>
> > 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?
>
> I made no such claim.

Ok, you did not claim data race.

> All I claim is that launching a thread in a constructor invokes
> undefined behaviour.  Nothing more, nothing less.

Then you should prove that claim of yours. Nothing more, nothing less.
But do that at last, please.

> You countered with "And the constructor does return. And the object is
> fully constructed.".  The new thread could run to completion before the
> constructor returned,

It depends. If it is a disjoint thread (not likely), yes. And then
nothing wrong is with it. If the thread needs interaction and the
conditions are not met, the thread cannot run to completion before the
constructor returns, of course.

> or the constructor could return before the thread
> runs.

That is also possible. No problem with that.

> Either is possible and neither is the specified scenario, because
> there isn't one.

What do you mean by "neither is the specified scenario, because there
isn't one."? Reference?

> Do you deny using an incomplete object doesn't invoke undefined behaviour?

There is no incomplete object. You are mistaken in that.

Let us take class A, you can use any method of class A in the
constructor of class A. (See "Member functions, including virtual
functions (10.3), can be called during construction or destruction")
Agreed?

A thread started as the last step in the constuctor of class A can
equally well call any member of class A. Remember that by convention
(see discipline) members of class A are initialised already. If the
thead would access any object from classes other than A then obviously
those objects are constructed already otherwise the thread would not
have any reference to them.

So, where is your problem? Where are the incomplete objects?

Finally try to prove something, please.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 18, 2008, 8:03:30 PM5/18/08
to

I try to get some proof out of you instead of you keep trolling.

Besides, I new you would escape instead of proving your claims. It is
the nature of trollers.

Best Regards,
Szabolcs

Ian Collins

unread,
May 18, 2008, 11:16:11 PM5/18/08
to
Szabolcs Ferenczi wrote:
> On May 19, 1:25 am, Ian Collins <ian-n...@hotmail.com> wrote:
>
>> You countered with "And the constructor does return. And the object is
>> fully constructed.". The new thread could run to completion before the
>> constructor returned,
>
> It depends. If it is a disjoint thread (not likely), yes. And then
> nothing wrong is with it. If the thread needs interaction and the
> conditions are not met, the thread cannot run to completion before the
> constructor returns, of course.
>
>> or the constructor could return before the thread
>> runs.
>
> That is also possible. No problem with that.
>
>> Either is possible and neither is the specified scenario, because
>> there isn't one.
>
> What do you mean by "neither is the specified scenario, because there
> isn't one."? Reference?
>
Well there isn't a reference, because it isn't defined. The C++
standard makes no mention of threads and POSIX for one does not define
the which thread is running after pthread_create. Either the parent,
the child or both may be running after the thread is created.

>> Do you deny using an incomplete object doesn't invoke undefined behaviour?
>
> There is no incomplete object. You are mistaken in that.
>

I'm not, an object is not complete until its constructor returns.

> Let us take class A, you can use any method of class A in the
> constructor of class A. (See "Member functions, including virtual
> functions (10.3), can be called during construction or destruction")
> Agreed?
>

Provided the virtual function is defined in the class or a base class.

> A thread started as the last step in the constuctor of class A can
> equally well call any member of class A. Remember that by convention
> (see discipline) members of class A are initialised already. If the
> thead would access any object from classes other than A then obviously
> those objects are constructed already otherwise the thread would not
> have any reference to them.
>
> So, where is your problem? Where are the incomplete objects?
>

Say the constructor uses one or more RAII style objects to manage
resources, even though the thread creation is the last visible call in
the constructor, the managed objects still have to be destroyed. Say
one of these operations fails and throws an exception which isn't
handled in the constructor. The constructor will then throw an
exception and the object's members will be cleaned up and the object
will not have been constructed. But the thread will still be running...

--
Ian Collins.

kasthurira...@gmail.com

unread,
May 19, 2008, 12:30:09 AM5/19/08
to

you may also want to look at www.kegel.com, especially http://www.kegel.com/c10k.html.
also, note that processes vs threads is platform dependent. you may
also look at apache's implementation for freebsd(mpm model).

Thanks,
Balaji.

Rolf Magnus

unread,
May 19, 2008, 12:42:12 AM5/19/08
to
ManicQin wrote:

> On May 18, 4:56 pm, James Kanze <james.ka...@gmail.com> wrote:
>
>> What are the constraints concerning shutdown? If you don't have
>> any (i.e. the only way to stop the process is to kill it), then
>> your connection threads are basically fire and forget: you don't
>> really need to keep any trace of them (which means that you
>> don't have any "thread" objects). In fact, unless the server
>> needs to access shared in memory data, it may be preferable to
>> use processes instead of threads. (That's what a lot of
>> traditional servers do: FTP, telnet, etc.)
>
>
> When you say processes do you mean different processes running
> and communicating via files\pipelines\sockets and so on?

Often, you don't have to communicate anything while the child process is
running. On posix systems, fork() is used to create a copy of the process,
so the child knows everything the parent knew when the child was created.

> 1) Wont it just complicate things?

Actually, I consider it simpler, provided that you don't need to communicate
much after the child has been created. And it has the advantage that if one
of the porcesses crashes, that won't affect the others. In a threaded
program, everything will go down. That's especially important for servers,
which could often go completely without concurrency, but use separate
processes for improved stability.

> 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 think that
> spliting your process to subs is a concept that is more acknowledged in
> linux \unix platforms then windows.

Not sure what you mean by "splitting your process to subs". Unix
traditionally does many of the things it wants to do parallel with separate
processes. Threads aren't used very often.
Since process creation is much more expensive under Windows, similar
programs need to use threads for performance reasons.

> 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!!!)

Yes. Copying a process with fork() is very fast. You don't get much of a
performance boost from using threads.


Ian Collins

unread,
May 19, 2008, 12:52:17 AM5/19/08
to
Rolf Magnus wrote:

> ManicQin wrote:
>
>> 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 think that
>> spliting your process to subs is a concept that is more acknowledged in
>> linux \unix platforms then windows.
>
> Not sure what you mean by "splitting your process to subs". Unix
> traditionally does many of the things it wants to do parallel with separate
> processes. Threads aren't used very often.

He used the term "sub processes" earlier in that paragraph.

Well that (Threads aren't used very often) was the case long ago, but
most things in Unix land (including the kernel) make heavy use of threads.

> Since process creation is much more expensive under Windows, similar
> programs need to use threads for performance reasons.
>
>> 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!!!)
>
> Yes. Copying a process with fork() is very fast. You don't get much of a
> performance boost from using threads.
>

You do if you have lots or create/destroy them frequently. A thread has
a lot less baggage than a process (especially no Linux has a decent
thread model).

--
Ian Collins.

darren

unread,
May 19, 2008, 1:38:52 AM5/19/08
to

> Yes. Copying a process with fork() is very fast. You don't get much of a
> performance boost from using threads.


I was reading this tutorial, and a table in the document describes a
process as being about 50x more expensive than a thread. Maybe I'm
interpreting the table wrong.
https://computing.llnl.gov/tutorials/pthreads/

Jerry Coffin

unread,
May 19, 2008, 1:58:32 AM5/19/08
to
In article <244547b2-0b90-45f1-a8f2-5ce84f7dd3e4
@k1g2000prb.googlegroups.com>, mino...@gmail.com says...

You seem to be interpreting the table correctly, but may not be
considering how that affects the server as a whole. The fact that one is
50x slower than the other doesn't mean that a server based on that model
would necessarily be 50x slower. Even though one's quite a bit faster
than the other, it creating new threads/processes should be a fairly
small percentage of overall time either way.

Of course, that depends heavily on the rest of the design. Quite a few
people try creating a new thread for every incoming connection. This
would almost certainly be disastrous if you created a new process for
every connection instead.

OTOH, if you create some sort of thread/process pool, then you only
incur that 50x overhead a few times while your server starts up. After
that, you might incur some overhead from inter- rather than intra-
process communication, but that's mostly a separate question.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Chris Thomasson

unread,
May 19, 2008, 2:54:22 AM5/19/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:f99c4d57-48cd-4623...@2g2000hsn.googlegroups.com...

On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:

> > Except that, as Chris has already pointed out, it results in a
> > race condition. It's a serious design error.

> 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.

The pseudo-code I post over on 'comp.programming.threads' is all about the
__experimental__ synchronization algorihtms that I am brainstorming. We have
been over this before Szabolcs. If I come up with an idea, I try to make
sure to post it on c.p.t. If there is a typo in the pseudo-code, I promptly
document them and show the corrections. Anyway...


> You better read carefully what I have written. I highlighted that one

> needs discipline for it. It is hopless for you but at least you calm
> down.

> I hope I could help though.

Unfortunately, wrt this thread, your so-called help is only going to lead
the OP down the wrong path. You don't seem to get it. AFAICT, the OP wanted
to create a thread base class for users to derive from. Something like:
____________________________________________________________________
class thread_base {
pthread_t m_tid;
virtual void on_entry() = 0;

thread_base() {
}

virtual ~thread_base() throw() = 0;
};

thread_base::~thread_base() throw() {}
____________________________________________________________________

The OP cannot start the thread from the constructor of the base class! This
is what I was referring to. When threads are involved there is a major
race-condition because the thread can be started and call the on_entry pure
virtual function which results in UB. Also, even in the absence of threads
there still can be a problem. Here is a VERY simple example:
____________________________________________________________________
#include <cstdio>
#include <cstdlib>


static void call_abstract_virtual_indirect(class base*);


class base {
friend void call_abstract_virtual_indirect(class base*);
virtual void on_action() = 0;

public:
base() {
call_abstract_virtual_indirect(this);
}

virtual ~base() throw() = 0;
};

base::~base() throw() {}


void call_abstract_virtual_indirect(base* _this) {
_this->on_action();
}


class derived : public base {
int const m_ctor;

public:
derived() : m_ctor(123456789) {

}

private:
void on_action() {
std::printf("(%p)::derived::on_action()\n", (void*)this);
if (m_ctor != 123456789) {
std::printf("(%p)::derived::on_action() - NOT CONSTRUCTED!\n",
(void*)this);
std::getchar();
std::abort();
}
}
};


int main() {
{
derived d;
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
std::puts("\n\n____________________________________________\n\
Press <ENTER> to exit...");
std::getchar();
return 0;
}

____________________________________________________________________


The above demonstrates one reason why its generally NOT a good idea to start
a thread in a constructor. Your failure to understand this is only going to
confuse the OP. Your advise is flawed in that respect. The problem produces
undefined-behavior. It can just seg-fault, or it might print "... NOT
CONSTRUCTED!", or whatever. Therefore, I guess the moral of the story is "Do
NOT call abstract virtual functions in constructors!"


:^o

Chris Thomasson

unread,
May 19, 2008, 3:02:32 AM5/19/08
to
"Ian Collins" <ian-...@hotmail.com> wrote in message
news:69c9nqF3...@mid.individual.net...

Also, if the threading is implemented as a base class with an abstract
virtual function representing the threads "entry" point, then you simply
cannot create the thread in the constructor. The thread might start running
and call the virtual function before the derived object has even had a
chance to run its ctor; OOPS! This is a major race-condition that Szabolcs
seems to think cannot ever happen. Perhaps I am misunderstanding him,
although, his arguments "seem" to suggest that he is not a C++ programmer...

;^/

Chris Thomasson

unread,
May 19, 2008, 3:13:19 AM5/19/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:53d7b28a-337b-4b8c...@a1g2000hsb.googlegroups.com...
On May 18, 11:43 am, darren <minof...@gmail.com> wrote:

> > 3. A successful accepted connection is put into a queue (from the STL
> > library).
> > 4. Meanwhile, back at the ranch, another thread is created and running
> > that continuously checks for entries into the queue.

> Be aware that although STL is thread-safe to a certain extent,

:^/

Where does the current C++ standard say that the STL is "thread-safe to a
certain extent"???

[...]

James Kanze

unread,
May 19, 2008, 5:04:41 AM5/19/08
to
On May 18, 10:41 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> Szabolcs Ferenczi wrote:
> > On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:

> >> Except that, as Chris has already pointed out, it results in a
> >> race condition. It's a serious design error.

> > 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.

Not to mention what happens if someone inherits from your class.
Starting the thread in a constructor is a well known
anti-pattern.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

unread,
May 19, 2008, 5:11:40 AM5/19/08
to
On May 19, 12:38 am, Gianni Mariani <gi4nos...@mariani.ws> wrote:
> 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.

And how do you ensure that? About the only way I know is to use
a separate object for the actual thread behavior. This is what
Boost does. (Java uses a separate function to start the thread,
which also works well.)

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

I'm not sure I understand you. Boost and Java use two radical
different models, yet both manage to avoid the problem.

James Kanze

unread,
May 19, 2008, 5:19:33 AM5/19/08
to

That is, IMHO, the cleanest solution. When it comes down to
it, the "object" you execute on isn't the thread; it's used by
the thread, so even from an OO point of view, it seems
preferable.

The alternative is to provide a separate function to start the
thread, as in Java. I personally don't see where this is a
problem either; it's just one additional function call after the
constructor. If the execution object has significant behavior,
it might even be preferable; it gives you a chance to intervene
after the constructor, but before the thread starts (e.g. to
register the object somewhere).

All in all, I don't really believe in the one size fits all
philosophy here, but if I had to stick to just one model, it
would be that of Boost, which executes a copy of the object you
pass it. It's a slight hassle in the case of joinable threads,
if you want to access the results in the thread object after the
join, but that's nothing that an extra layer of indirection
can't fix. (Back in the old days, it was widely believed that
there was no problem which couldn't be solved by an extra layer
of indirection:-).) (What bothers me most about the Boost model
is that if you miss catching an exception somewhere, you end up
with a detached thread, when what you wanted was to terminate
and join.)

James Kanze

unread,
May 19, 2008, 5:22:18 AM5/19/08
to
On May 19, 9:13 am, "Chris Thomasson" <cris...@comcast.net> wrote:
> "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message

> :^/

And the implementations I use are completely thread safe, not
just to a certain extent. The document very clearly what is and
is not guaranteed (even if what they guarantee is somewhat
surprising in the case of g++, since it contradicts Posix).

James Kanze

unread,
May 19, 2008, 5:26:05 AM5/19/08
to
On May 18, 3:43 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:
> On May 18, 3:27 pm, James Kanze <james.ka...@gmail.com> wrote:
> > On 18 mai, 13:29, ManicQin <Manic...@gmail.com> wrote:

> > > On May 18, 12:43 pm, darren <minof...@gmail.com> wrote:

> > [...]

> > > > Try to avoid using singletons (if you refer to the
> > > > singleton pattern). It is not a good idea even in
> > > > non-MT programs. You can always avoid using singletons
> > > > by disciplined programming. In this case you do not need
> > > > singleton either.
> > > He is right

> > Bullshit. (If you read any of Szabolcs' postings, you'll
> > quickly realize that he's never actually written any real code.)
> > You don't want to abuse them, but there are special cases where
> > they are the appropriate solution. In the case of detached
> > threads, in fact, some form of singleton is almost necessary for
> > a clean shutdown.

> Calm down, my friend, and do not write "Bullshit".

I call a spade a spade. If you don't post bullshit, I won't
respond with "bullshit".

> If you do not know about something, do not attack it just
> because of your ignorance.

Look who's talking.

> The singleton pattern is discouraged even by its creator.

Given that the pattern has been around for years, I doubt that
we even know who its creator is. The fact remains that it is
the best known solution for a small number of particular cases.
Just because it can be (and frequently is) misused doesn't mean
it shouldn't be used where appropriate. (There is, in fact, no
other way to ensure clean shutdown if you're using detached
threads.)

James Kanze

unread,
May 19, 2008, 5:37:25 AM5/19/08
to
On May 19, 7:58 am, Jerry Coffin <jcof...@taeus.com> wrote:
> In article <244547b2-0b90-45f1-a8f2-5ce84f7dd3e4
> @k1g2000prb.googlegroups.com>, minof...@gmail.com says...

> > > Yes. Copying a process with fork() is very fast. You don't get much of a
> > > performance boost from using threads.

> > I was reading this tutorial, and a table in the document describes a
> > process as being about 50x more expensive than a thread. Maybe I'm
> > interpreting the table wrong.
> >https://computing.llnl.gov/tutorials/pthreads/

> You seem to be interpreting the table correctly,

Note that that document doesn't specify which OS is being used,
or---in the case of Linux, which threading model. (Note that
some threading models do not allow multiple threads within a
single process to execute on different CPU's. That makes thread
creation very cheap, but sort of defeats the purpose of having
multiple CPU's.)

[...]


> Of course, that depends heavily on the rest of the design.
> Quite a few people try creating a new thread for every
> incoming connection. This would almost certainly be disastrous
> if you created a new process for every connection instead.

That really depends on what the protocol is doing. FTP and
telnet, at least in the implementations I use, spawn a separate
process for each connection.

> OTOH, if you create some sort of thread/process pool, then you
> only incur that 50x overhead a few times while your server
> starts up. After that, you might incur some overhead from
> inter- rather than intra- process communication, but that's
> mostly a separate question.

Process pools are a lot more difficult to manage than thread
pools, because you do have to communicate with a running process
in order to use them. (Although... under Solaris, at least, you
can put conditions and mutexes in shared memory, and access them
from different processes. so the difference isn't that great.)

--
James Kanze (GABI Software) email:james...@gmail.com

Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

James Kanze

unread,
May 19, 2008, 5:50:24 AM5/19/08
to
On May 18, 11:00 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:
> On May 18, 9:59 pm, James Kanze <james.ka...@gmail.com> wrote:

> > On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> > wrote:

> > > On May 18, 3:56 pm, James Kanze <james.ka...@gmail.com> wrote:
> > ...
> > 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 I'm one of the experts in the French national body, yes.
I'm very much aware about what is going into the standard.

> since you were trolling in the other discussion
> thread in "Threading in new C++ standard" too,

The only troll in that thread was you. You refuse to read and
understand the published documentation, and you've obviously no
real experience with large working multithreaded applications,
but you continue with argumentive posts questionning the
competence of the real experts.

> 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.

And that is simply a lie.

> 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.

Threading is handled in �1.9 of the latest draft (amongst other
places). This was pointed out to you in the other thread as
well, but you refuse to read anything which doesn't conform to
your prejudices.

> > ... 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.)

The only thing you've done to date is make a lot of vacuous
claims, unsupported by any real facts. The experts in the
matter don't share your prejudices. Nor do those of us actually
involved in writing working applications.

Ian Collins

unread,
May 19, 2008, 7:51:58 AM5/19/08
to
Chris Thomasson wrote:
>
> Also, if the threading is implemented as a base class with an abstract
> virtual function representing the threads "entry" point, then you simply
> cannot create the thread in the constructor.

I was saving that one for the next round!

--
Ian Collins.

Szabolcs Ferenczi

unread,
May 19, 2008, 12:04:21 PM5/19/08
to
On May 19, 8:54 am, "Chris Thomasson" <cris...@comcast.net> wrote:
> "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
> The above demonstrates ...

Well, the above demonstrates that a hacker can misuse any formal
system.

Kurt Goedel can be very pleased now up there since slaves are working
for him down here.

Congratulations!

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 19, 2008, 12:15:43 PM5/19/08
to
On May 19, 5:16 am, Ian Collins <ian-n...@hotmail.com> wrote:
> Szabolcs Ferenczi wrote:
> > On May 19, 1:25 am, Ian Collins <ian-n...@hotmail.com> wrote:
>
> >> You countered with "And the constructor does return. And the object is
> >> fully constructed.".  The new thread could run to completion before the
> >> constructor returned,
>
> > It depends. If it is a disjoint thread (not likely), yes. And then
> > nothing wrong is with it. If the thread needs interaction and the
> > conditions are not met, the thread cannot run to completion before the
> > constructor returns, of course.
>
> >> or the constructor could return before the thread
> >> runs.
>
> > That is also possible. No problem with that.
>
> >>  Either is possible and neither is the specified scenario, because
> >> there isn't one.
>
> > What do you mean by "neither is the specified scenario, because there
> > isn't one."?  Reference?
>
> Well there isn't a reference, because it isn't defined.

If you cannot give any reference what are you referring to then? What
is the specified scenario? Reference please to the specified scenario.
You are talking about something that is not defined?

> The C++
> standard makes no mention of threads

That is what I have started my contribution with to this discussion
thread.
"C++ does not have the notion of the process or the thread of
computation at the language level."
http://groups.google.com/group/comp.lang.c++/msg/6413d1c864883be3
Good morning. At least you woke up now.

> and POSIX for one does not define
> the which thread is running after pthread_create.  Either the parent,
> the child or both may be running after the thread is created.

Who argues with you in that? You should not make any assumption about
the relative speed of the threads of computation.

> >> Do you deny using an incomplete object doesn't invoke undefined behaviour?
>
> > There is no incomplete object. You are mistaken in that.
>
> I'm not, an object is not complete until its constructor returns.

Reference please. Where is it defined in the C++ standard? A
constructor is just a method that is called automatically. It is your
responsibility to fully initialise the state space you are using and
you can do that in the constructor. Once you are done with it, it is
complete. So simple is it.

Again you are invited to give a reference to prove your claim. Until
you cannot prove any reference, you are mistaken.

> > Let us take class A, you can use any method of class A in the
> > constructor of class A. (See "Member functions, including virtual
> > functions (10.3), can be called during construction or destruction")
> > Agreed?
>
> Provided the virtual function is defined in the class or a base class.

Where else? Are you trying to argue with the standard now? I have
quoted from the standard.

> > A thread started as the last step in the constuctor of class A can
> > equally well call any member of class A. Remember that by convention
> > (see discipline) members of class A are initialised already. If the
> > thead would access any object from classes other than A then obviously
> > those objects are constructed already otherwise the thread would not
> > have any reference to them.
>
> > So, where is your problem? Where are the incomplete objects?
>
> Say the constructor uses one or more RAII style objects to manage
> resources, even though the thread creation is the last visible call in
> the constructor, the managed objects still have to be destroyed.

Yes, so arrange it that your managed objects should be destroyed. Once
you introduce some hack, you have to do that properly. You must
arrange that your managed objects be destroyed properly.

> Say
> one of these operations fails and throws an exception which isn't
> handled in the constructor.

Well, you must handle it in the constructor. If you do not handle it
in the constructor, it is your fault. Simple, isn't it?

> The constructor will then throw an
> exception and the object's members will be cleaned up and the object
> will not have been constructed.  But the thread will still be running...

If you build your code like that, yes, you are in trouble.

However, with the same effort one can program it properly as well. For
instance, you can try try. Define your RAII hack in a try block, catch
and handle exceptions and when everything is finished properly, you
can launch the thread safely. Otherwise you must cach and handle the
exception. Can't you do that? What is your problem?

> --
> Ian Collins.- Hide quoted text -

So, where are the incomplete objects after all?

Earlier you said: "All I claim is that launching a thread in a


constructor invokes undefined behaviour. Nothing more, nothing less."

http://groups.google.com/group/comp.lang.c++/msg/856389deef6a40c0

Please prove that claim of yours. Nothing more, nothing less. Where is
the undefined behaviour?

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 19, 2008, 12:45:03 PM5/19/08
to
On May 19, 11:50 am, James Kanze <james.ka...@gmail.com> wrote:
> On May 18, 11:00 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> wrote:
>
> > On May 18, 9:59 pm, James Kanze <james.ka...@gmail.com> wrote:
> > > On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> > > wrote:
> > > > On May 18, 3:56 pm, James Kanze <james.ka...@gmail.com> wrote:
> > > ...
> > > 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 I'm one of the experts in the French national body, yes.
> I'm very much aware about what is going into the standard.

Very well. That explains a lot about the French contribution. You like
to talk big, don't you.

> > 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.
>
> And that is simply a lie.

Is it?

Why do not you just calm down? Are you so notorious.

How about this:

<quote>
23. Pete Becker View profile More options Apr 20, 7:04 pm
On 2008-04-20 12:36:50 -0400, James Kanze <james.ka...@gmail.com>
said:

> There was never a proposal for introducing the
> threading API at the language level, however; that just seems
> contrary to the basic principles of C++, and in practice, is
> very limiting and adds nothing.

There actually was a proposal for threading at the language level:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1875.html.
...
</quote>
http://groups.google.com/group/comp.lang.c++/msg/1ea5fdf80fd7f461

Q.E.D.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 19, 2008, 1:08:10 PM5/19/08
to
On May 19, 11:22 am, James Kanze <james.ka...@gmail.com> wrote:
> On May 19, 9:13 am, "Chris Thomasson" <cris...@comcast.net> wrote:
>
> > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
> >news:53d7b28a-337b-4b8c...@a1g2000hsb.googlegroups.com...
> > On May 18, 11:43 am, darren <minof...@gmail.com> wrote:
> > > > 3. A successful accepted connection is put into a queue (from the STL
> > > > library).
> > > > 4. Meanwhile, back at the ranch, another thread is created and running
> > > > that continuously checks for entries into the queue.
> > > Be aware that although STL is thread-safe to a certain extent,
> > :^/
> > Where does the current C++ standard say that the STL is
> > "thread-safe to a certain extent"???
>
> And the implementations I use are completely thread safe, not
> just to a certain extent.

After all your talking big, I doubt it, but if you wrapped the STL up,
maybe. But I am not sure about you.

Can you show me how do you solve with plain STL container that two
consumer process are awaiting elements?

No, you can't, until you wrap the STL and make the wrapped container
thread safe.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 19, 2008, 1:10:30 PM5/19/08
to
On May 19, 9:13 am, "Chris Thomasson" <cris...@comcast.net> wrote:
> "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message

>
> news:53d7b28a-337b-4b8c...@a1g2000hsb.googlegroups.com...
> On May 18, 11:43 am, darren <minof...@gmail.com> wrote:
>
> > > 3. A successful accepted connection is put into a queue (from the STL
> > > library).
> > > 4. Meanwhile, back at the ranch, another thread is created and running
> > > that continuously checks for entries into the queue.
> > Be aware that although STL is thread-safe to a certain extent,
>
> Where does the current C++ standard say that the STL is "thread-safe to a
> certain extent"???

For instance here:
"The SGI implementation of STL is thread-safe only in the sense that
simultaneous accesses to distinct containers are safe, and
simultaneous read accesses to to shared containers are safe. If
multiple threads access a single container, and at least one thread
may potentially write, then the user is responsible for ensuring
mutual exclusion between the threads during the container accesses. "

http://www.sgi.com/tech/stl/thread_safety.html

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 19, 2008, 1:14:12 PM5/19/08
to
On May 19, 6:42 am, Rolf Magnus <ramag...@t-online.de> wrote:

> Yes. Copying a process with fork() is very fast. You don't get much of a
> performance boost from using threads.

Did you ever hear about heavy weight and light weight processes? I am
just curious.

Best Regards,
Szabolcs

gpderetta

unread,
May 19, 2008, 2:01:40 PM5/19/08
to
On May 19, 6:45 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>

wrote:
> On May 19, 11:50 am, James Kanze <james.ka...@gmail.com> wrote:
>
> > On May 18, 11:00 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> > wrote:
> > > 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.
>
> > And that is simply a lie.
>
> Is it?
> [...]

>
> How about this:
>
> <quote>
> 23.  Pete Becker    View profile   More options Apr 20, 7:04 pm
> On 2008-04-20 12:36:50 -0400, James Kanze <james.ka...@gmail.com>
> said:
>
> > There was never a proposal for introducing the
> > threading API at the language level, however; that just seems
> > contrary to the basic principles of C++, and in practice, is
> > very limiting and adds nothing.
>
> There actually was a proposal for threading at the language level:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1875.html.
> ...
> </quote>http://groups.google.com/group/comp.lang.c++/msg/1ea5fdf80fd7f461
>
> Q.E.D.

Nope:

"threading API at the language level" != "threading at the language
level"

C++ will have threading at the language level, but you will not be
able to
access the threading primitives via keywords; instead, you will have
to access
them through standard library based wrappers. Of course an
implementer,
as a conforming extension, is free to expose the underlying
implementation primitives,
if there are any.

--
gpd

gpderetta

unread,
May 19, 2008, 2:08:03 PM5/19/08
to
On May 19, 7:14 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

On modern unices, there isn't much of a difference between a process
and a thread,
except that processes do not share the address space (and other minor
differences).
Unsharing is done with copy on write, so as long as the child process
do not touch
parent data, forking is very, very, fast.

Context switching a process instead of a thread requires, on modern
architectures,
invalidating the TLB (but there are ways around that), which is
moderately expensive,
but not excessively so (with a big enough timeslice, you won't notice
the difference).

HTH,

--
gpd

gpderetta

unread,
May 19, 2008, 2:13:05 PM5/19/08
to
On May 19, 7:10 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

Yes, in that sense is thread safe.

In fact, short of having transactional memory (which allows arbitrary
composition of atomic operations) it is, arguably, the only useful
sense.

Unfortunately (efficient) transactional memory is mostly an academic
topic.

BTW, IIRC the incoming C++ standard will guarantee the same thread
safety
stated in the SGI document (which is, of course, not the standard).

--
gpd


Szabolcs Ferenczi

unread,
May 19, 2008, 2:23:24 PM5/19/08
to
On May 19, 8:13 pm, gpderetta <gpdere...@gmail.com> wrote:
> On May 19, 7:10 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> wrote:
>
>
>
> > On May 19, 9:13 am, "Chris Thomasson" <cris...@comcast.net> wrote:
>
> > > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
>
> > >news:53d7b28a-337b-4b8c...@a1g2000hsb.googlegroups.com...
> > > On May 18, 11:43 am, darren <minof...@gmail.com> wrote:
>
> > > > > 3. A successful accepted connection is put into a queue (from the STL
> > > > > library).
> > > > > 4. Meanwhile, back at the ranch, another thread is created and running
> > > > > that continuously checks for entries into the queue.
> > > > Be aware that although STL is thread-safe to a certain extent,
>
> > > Where does the current C++ standard say that the STL is "thread-safe to a
> > > certain extent"???
>
> > For instance here:
> > "The SGI implementation of STL is thread-safe only in the sense that
> > simultaneous accesses to distinct containers are safe, and
> > simultaneous read accesses to to shared containers are safe. If
> > multiple threads access a single container, and at least one thread
> > may potentially write, then the user is responsible for ensuring
> > mutual exclusion between the threads during the container accesses. "
>
> >http://www.sgi.com/tech/stl/thread_safety.html
>
> Yes, in that sense is thread safe.

Please explain it to the forum fighters.

Best Regards,
Szabolcs

gpderetta

unread,
May 19, 2008, 2:43:38 PM5/19/08
to
On May 19, 8:23 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>

No need. They all, especially James Kanze, know very well.

That's way they say that it is completely thread safe: as long
as you follow some simple rules, most standard library
implementations work perfectly well in threaded programs.

--
Giovanni P. Deretta

Szabolcs Ferenczi

unread,
May 19, 2008, 3:22:35 PM5/19/08
to

Are you suggesting that he intentionally makes fool of himself?
http://groups.google.com/group/comp.lang.c++/msg/bf81088bfec40dab

Or do you rather think that he just gets excited whenever he sees any
statement from me and he starts contradicting anything just blindly?
Is it a conditioned reflex by him then?

Best Regards,
Szabolcs

gpderetta

unread,
May 19, 2008, 5:44:35 PM5/19/08
to
On May 19, 9:22 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>

Please, let's grow up. I do not see how James makes fool of himself.
Quite the contrary in fact.

> Or do you rather think that he just gets excited whenever he sees any
> statement from me and he starts contradicting anything just blindly?
> Is it a conditioned reflex by him then?
>

No, it is just that this is a very high volume C++ newsgroup, and
any incorrect statement which goes uncorrected might confuse
newbies (or even experts which are not familiar with some niche
details).

Let's continue this discussion just on a technical level.

--
gpd

Rolf Magnus

unread,
May 20, 2008, 12:42:52 AM5/20/08
to
darren wrote:

>
>> Yes. Copying a process with fork() is very fast. You don't get much of a
>> performance boost from using threads.
>
>

> I was reading this tutorial, and a table in the document describes a
> process as being about 50x more expensive than a thread. Maybe I'm
> interpreting the table wrong.

I tried the test programs from that table on my system, and the factor there
was around 7. Anyway, such a comparison doesn't say much, since a
real-world program does some actual work and not just spawn off
processes/threads. And then, it only matters how much time the spawning
costs compared to the time for the actual work.

James Kanze

unread,
May 20, 2008, 5:23:59 AM5/20/08
to
On May 19, 7:08 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

> On May 19, 11:22 am, James Kanze <james.ka...@gmail.com> wrote:
> > On May 19, 9:13 am, "Chris Thomasson" <cris...@comcast.net> wrote:

> > > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
> > >news:53d7b28a-337b-4b8c...@a1g2000hsb.googlegroups.com...
> > > On May 18, 11:43 am, darren <minof...@gmail.com> wrote:
> > > > > 3. A successful accepted connection is put into a queue (from the STL
> > > > > library).
> > > > > 4. Meanwhile, back at the ranch, another thread is created and running
> > > > > that continuously checks for entries into the queue.
> > > > Be aware that although STL is thread-safe to a certain extent,
> > > :^/
> > > Where does the current C++ standard say that the STL is
> > > "thread-safe to a certain extent"???

> > And the implementations I use are completely thread safe, not
> > just to a certain extent.

> After all your talking big, I doubt it, but if you wrapped the STL up,
> maybe. But I am not sure about you.

I haven't wrapped anything. And judging from your previous
postings, I doubt you know what thread safety means, so I'm not
sure what your doubting means.

> Can you show me how do you solve with plain STL container that
> two consumer process are awaiting elements?

Can you ask a question that makes sense. STL containers are
data containers, they aren't thread synchronization elements.

> No, you can't, until you wrap the STL and make the wrapped
> container thread safe.

As I said, it's obvious that you don't know what "thread safe"
means.

James Kanze

unread,
May 20, 2008, 5:26:28 AM5/20/08
to
On May 19, 7:10 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

> http://www.sgi.com/tech/stl/thread_safety.html

As others will no doubt point out, that document isn't the
standard, and only applies to a specific implementation. Other
than that, can you give some other definition of "thread safe"
which would be applicable to the standard containers. That is
not "thread-safe to a certain extent", that is "thread-safe",
pure and simple.

James Kanze

unread,
May 20, 2008, 5:32:08 AM5/20/08
to
On May 19, 8:13 pm, gpderetta <gpdere...@gmail.com> wrote:
> On May 19, 7:10 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> wrote:

[...]


> > For instance here:
> > "The SGI implementation of STL is thread-safe only in the sense that
> > simultaneous accesses to distinct containers are safe, and
> > simultaneous read accesses to to shared containers are safe. If
> > multiple threads access a single container, and at least one thread
> > may potentially write, then the user is responsible for ensuring
> > mutual exclusion between the threads during the container accesses. "

> >http://www.sgi.com/tech/stl/thread_safety.html

> Yes, in that sense is thread safe.

> In fact, short of having transactional memory (which allows
> arbitrary composition of atomic operations) it is, arguably,
> the only useful sense.

I'm not too sure what you mean by transactional memory. In
general, however, containers that's the only useful sense of
thread safety for containers which "leak" references to internal
objects.

More importantly: the implementor here has *documented* the
contract which the implemention provides. And *that* is the key
meaning behind thread safety. Thread safety is first and
foremost a question of documentation.

> Unfortunately (efficient) transactional memory is mostly an
> academic topic.

Aha. That's why I'm not too familiar with it.

> BTW, IIRC the incoming C++ standard will guarantee the same
> thread safety stated in the SGI document (which is, of course,
> not the standard).

That's the basic intention. I believe that there are a few
small open issues, but the basic philosophy is the same as that
in the SGI implementation.

James Kanze

unread,
May 20, 2008, 5:36:35 AM5/20/08
to
On May 19, 9:22 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>

wrote:
> On May 19, 8:43 pm, gpderetta <gpdere...@gmail.com> wrote:
> > On May 19, 8:23 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> > wrote:
> > > > > For instance here:
> > > > > "The SGI implementation of STL is thread-safe only in
> > > > > the sense that simultaneous accesses to distinct
> > > > > containers are safe, and simultaneous read accesses to
> > > > > to shared containers are safe. If multiple threads
> > > > > access a single container, and at least one thread may
> > > > > potentially write, then the user is responsible for
> > > > > ensuring mutual exclusion between the threads during
> > > > > the container accesses. "

> > > > >http://www.sgi.com/tech/stl/thread_safety.html

> > > > Yes, in that sense is thread safe.

> > > Please explain it to the forum fighters.

> > No need. They all, especially James Kanze, know very well.

> Are you suggesting that he intentionally makes fool of
> himself?http://groups.google.com/group/comp.lang.c++/msg/bf81088bfec40dab

Do you understand English? The SGI statement says exactly what
I said, that the implementation is thread safe. (At least two
of the implementations I use are derived almost directly from
the SGI implementation.)

The problem I see here is that you don't know what thread-safe
means.

> Or do you rather think that he just gets excited whenever he
> sees any statement from me and he starts contradicting
> anything just blindly? Is it a conditioned reflex by him
> then?

It's a more or less conditioned reflex on my part to correct
errors which people post, so that beginners don't get mislead.
The fact that you tend to post mostly errors does lead to my
correcting your postings more than those of other people.

gpderetta

unread,
May 20, 2008, 8:33:11 AM5/20/08
to
On May 20, 11:32 am, James Kanze <james.ka...@gmail.com> wrote:
> On May 19, 8:13 pm, gpderetta <gpdere...@gmail.com> wrote:
> > In fact, short of having transactional memory (which allows
> > arbitrary composition of atomic operations) it is, arguably,
> > the only useful sense.
>
> I'm not too sure what you mean by transactional memory.  

As far as I can understand, a transactional memory runs under
optimistic concurrent assumptions: concurrent operations are
exectued in explicitly marked atomic blocks, and run
speculatively. At the end of the atomic block, if the system
detects that no race condition occurred, the the transaction
is allowed to commit, (i.e. its effects are made visible to
the system), else it is rolled back and optionally retried.

For example, a thread safe queue under a TM model would have
its enqueue and dequeue methods each wrapped in a atomic block.

What makes transactional memory very different from other forms
of concurrency control is composability: you can nest atomic
blocks and logically enlarge transaction scope:

tm_queue a;
tm_queue b;

atomic {
x = a.deq()
b.deq(x)
}

This block guarantees that other threads will see x in queue a OR
in queue b (never in both queues or in neither). This sort of
atomic omposability is quite a powerful abstraction which is hard
to do generically with lock based designs.

The problem of course that implementing transactional memory without
hardware support not only requires language support, but it is quite
expensive. I think that current software implementations of TM are
at most half as fast as lock based models in the non contented case.

In case of many aborts, performance can degrade quickly, so STM might
not scale very well.

So far the only system which support a form of TM in hardware are the
last SPARC systems from SUN (by sort-of-hijacking the cache coherency
protocol).

Another problem of TM is that in most practical implementations it is
possible to livelock (even if unlikely).

Real experts might be able to correct any errors in my explaination
or explain more.

> In general, however, containers that's the only useful sense of
> thread safety for containers which "leak" references to internal
> objects.
>
> More importantly: the implementor here has *documented* the
> contract which the implemention provides.  And *that* is the key
> meaning behind thread safety.  Thread safety is first and
> foremost a question of documentation.
>

agree 100%

--
gpd

werasm

unread,
May 20, 2008, 12:37:07 PM5/20/08
to
On May 17, 10:20 pm, darren <minof...@gmail.com> wrote:
> Hi
>
> I have to write a multi-threaded program. I decided to take an OO
> approach to it. I had the idea to wrap up all of the thread functions
> in a mix-in class called Threadable. Then when an object should run
> in its own thread, it should implement this mix-in class. Does this
> sound like plausible design decision?
>
> I'm surprised that C++ doesn't have such functionality, say in its
> STL. This absence of a thread/object relationship in C++ leads me to
> believe that my idea isn't a very good one.
>
> I would appreciate your insights. thanks

We've create a framework that uses commands (GOF command pattern)
to perform inter threading communication. If the applicable
command (a member function/instance combination) is associated
with a context, it executes in that context, else it executes
in its own.

All context objects merely have on static function that
processes the next command on the queue. Application
programmers in general don't think about threading, as
it is opaque whether commands are associated with threads
or not.

In general we prevent the race conditions mentioned by
halting on a binary semaphore in the task function and
explicitly activating tasks after construction. This is
typically done by an object that is responsible for
creation of all domain objects (objects associated with
context).

Typically the context function looks like this:

int CmdMngrTaskPosix::taskEntryPoint( CmdMngrTaskPosix* inst )
{
//Wait for activation
inst->activateSem_->acquire();
inst->execState_ = eExecutionState_Activated;

while( inst->execState_ == eExecutionState_Activated )
{
inst->serviceCmdQueue();
}
//It is highly unlikely that more commands would exists
//on the queue after terminate, but flush anyway.
inst->flush();

//This is called to release the destructSem_ semaphore
// that is waiting for the task to be completed.
// destructSem_ will be acquired during either destruction
// or a call to terminateExecution().
inst->destructSem_->release();

return EXIT_SUCCESS;
}


Typically we make use of template method to create all objects,
whereafter we start tasks. Obviously tasks can be created on
the fly, but the creation and the activation is separated. Each
context (or task) has interface that allows for the mailing of
commands on its queue. Commands can consist of either member
functions or non-member functions. They are cloned prior to
mailing over queues. Arguments to the commands are stored
as pointers and usually ownership transferral occurs,
depending on the size of the argument type.

Destruction of a Context Object gets done from an orthogonal
context (typically the creator) and the destroyer is forced
to block until the context exits successfully.

All said, it's quite a large excursion to undertake, but works
quite nicely and allows the application programmer to not
think "Threads".

Regards,

Werner

Szabolcs Ferenczi

unread,
May 20, 2008, 3:26:51 PM5/20/08
to

Hmmmm...

> "threading API at the language level" != "threading at the language
> level"

"language level" != "API"

> C++ will have threading at the language level, but you will not be
> able to
> access the threading primitives via keywords;

Then it is not at the language level. Do you know at all what language
is?

Some of you could admit already in another discussion thread that C+
+0x does not provide threading at the language level. Check out these
questions:

1) How do you create a thread of computation in C++0x? With library
calls or at language level?

2) How do you define critical region in C++0x? With library calls or
at language level?

3) How do you let the threads of computation synchronise with each
other in C++0x? With library calls or at language level?

If you try to answer these simple questions, you might find the answer
to whether C++0x provides threading at the language level or at the
library level.

> instead, you will have
> to access
> them through standard library based wrappers.

That is the library itself. However, your claim just means that for
the C++0x programmer threading is at the library level and not at the
language level.

As I said in the other discussion thread, there would be no problem if
you guys could admit the truth, namely, that what C++0x will provide
is nothing else but yet another threading library.

You know, calling a library API a language is dissonant.

Maybe the committee wanted to design a horse but it is going to be a
camel. A camel is beautiful creature as a camel but it is an ugly one
as a horse, and vice versa. The problem comes when you want to name a
camel a horse.

Best Regards,
Szabolcs

Szabolcs Ferenczi

unread,
May 20, 2008, 4:26:45 PM5/20/08
to
On May 20, 11:36 am, James Kanze <james.ka...@gmail.com> wrote:
> On May 19, 9:22 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> wrote:
>
> > On May 19, 8:43 pm, gpderetta <gpdere...@gmail.com> wrote:
> > > On May 19, 8:23 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
> > > wrote:
> > > > > > For instance here:
> > > > > > "The SGI implementation of STL is thread-safe only in
> > > > > > the sense that simultaneous accesses to distinct
> > > > > > containers are safe, and simultaneous read accesses to
> > > > > > to shared containers are safe. If multiple threads
> > > > > > access a single container, and at least one thread may
> > > > > > potentially write, then the user is responsible for
> > > > > > ensuring mutual exclusion between the threads during
> > > > > > the container accesses. "
> > > > > >http://www.sgi.com/tech/stl/thread_safety.html
> > > > > Yes, in that sense is thread safe.
> > > > Please explain it to the forum fighters.
> > > No need. They all, especially James Kanze, know very well.
> > Are you suggesting that he intentionally makes fool of
> > himself?http://groups.google.com/group/comp.lang.c++/msg/bf81088bfec40dab

You ask:

> Do you understand English?

I guess so.

> The SGI statement says exactly what
> I said, that the implementation is thread safe.

SGI statement simply contradicts you: "If multiple threads access a


single container, and at least one thread may potentially write, then

THE USER IS RESPONSIBLE FOR ENSURING MUTUAL EXCLUSION BETWEEN THE
THREADS during the container accesses." It is just safe for reading,
so what I said was correct that it is thread safe to a certain extent.
The SGI also confirms me: "The SGI implementation of STL is thread-
safe ONLY IN THE SENSE that ..." That is it is not "completely thread
safe" as you claimed. You like to talk big, don't you?

Now let us see what I said and what you and other mental guys with
conditioned reflex attacked like mad:

"Be aware that although STL is thread-safe to a certain extent, you
must wrap around the STL data structure to make a kind of a bounded
buffer out of it."
http://groups.google.com/group/comp.lang.c++/msg/4450c4f92d6e0211

Besides, you still must show us how can you get elements from the
plain "completely thread safe" STL containers with multiple consumers.
(You cannot show this because you just talk big as usual.)

> > Or do you rather think that he just gets excited whenever he
> > sees any statement from me and he starts contradicting
> > anything just blindly?  Is it a conditioned reflex by him
> > then?
>
> It's a more or less conditioned reflex on my part to correct
> errors which people post, so that beginners don't get mislead.

I had a strong feeling that you have mental problem.

Best Regards,
Szabolcs

gpderetta

unread,
May 20, 2008, 5:45:55 PM5/20/08
to
On May 20, 9:26 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>

*sigh*. We have been trying to explain it painfully to you for a long
time.

In C++ land, the "C++ language" is the standard defined in the
ISO/IEC 14882:2003 document, no more no less.

This document include both a keyword based interface (also called
core) and a library based interface (also called standard library),
both interfaces together make the C++ language (a freestanding
implementation my lack part but not all of the standard library).

Notice that the distinction between core and library is purely
a matter of convenience, and is more due to historical reasons
than anything (if C++ were rewritten today, core would be even
smaller).

Just because some parts are classified as "library" it doesn't
means that it must actually be implemented as a library:
std::vector for all purposes might as well be a special keyword:
same thing for std::string.

Sometimes the distinction between the core and library part
is very fuzzy: consider placement new: it is for all intent
and purposes a very primitive builtin, but in theory it should
be defined in the <new> header. Or the builting typeid, which
needs header <type_info> for support. The new range based
for loop, a variant of the classic 'for' also need a support
header.

But I'm sure this won't convince you. Let's take another route:

think about a language like java, which has explicit
synchronized {} blocks. Certainly, by all definitions, this
is language support for threading (even if I'm sure it doesn't fit
your vision of good language threading support).

Let's consider a little variant of java/c++ hybrid with a
builtin mutex type, where the synchronized block take
the mutex explicitly as a parameter (instead of implicitly
like in java), and obvious semantics.

mutex m;
...
synchronized(m) {
// do something in mutual exclusion
}

So far so good.
An user is free to do this:

class my_mutex {
friend my_synchronized;
private:
mutex m;
};

template<template Body>
void my_synchronized(Body b, my_mutex m) {
synchronized(m.m) {
b();
}
}

Use them like this:

my_mutex m;

my_synchronized(
lambda()
{ /* body in mutual exclusion here */ }
, m
);


So far, so good, certainly threading is still at the language level.

Let's say that, for whatever reasons, the language designers, liked
both my_mutex and my_synchronized so much that decided that these
are the primary meaning to access synchronization primitives, and
eventually relegated mutex and synchronized as implementation
detail and no longer accessible to user code.

Would this remove suddenly threading support from the language?
I'm sure that you can come up with some definition which will
support your view, but it will be a very narrow minded one (
which will value syntactic sugar more than semantics)

This is exactly the situation in C++: my_mutex is spelled
std::mutex (and other beasts), and, instead of my_synchronized,
we use scoped locks, as higher order functions are a bit
cumbersome in C++.

What matters are the semantics, not the syntactic sugar. C++0x
certainly has well defined multi threaded semantics, even if
the syntax might not have all the bell and whistles of other
languages.

In C++03, there were still no pure library based thread packages:
posix, openmp, even win32, all define a dialect
of C++ which add thread semantics to C++ (actually C).
Unfortunately, so far, all this bolt on additions have been
less than perfect, bug prone, and lacking in corner areas.

C++0x try to fix all these problems, in part by standardizing
existing work, in part by explicitly specifying which threaded
programs are legal, and finally expanding the state of the art
(of C++) a bit by adding atomic primitives.

--
gpd

Szabolcs Ferenczi

unread,
May 20, 2008, 7:34:04 PM5/20/08
to
On May 20, 11:45 pm, gpderetta <gpdere...@gmail.com> wrote:

> think about a language like java, which has explicit
> synchronized {} blocks. Certainly, by all definitions, this
> is language support for threading (even if I'm sure it doesn't fit
> your vision of good language threading support).

The `synchronized {} blocks' are language support for specifying
Critical Regions but, you are right, it is not correctly defined in
Java.

> Let's consider a little variant of java/c++ hybrid with a
> builtin mutex type, where the synchronized block take
> the mutex explicitly as a parameter (instead of implicitly
> like in java), and obvious semantics.
>
>   mutex m;
>   ...
>   synchronized(m) {
>      // do something in mutual exclusion
>   }
>
> So far so good.

So far not so good at all.

1) First of all the mutex is a library level tool. It is not a
language tool. It shall not appear at the language level. The mutex is
part of the library-based solution for achieving mutual exclusion of
the processes. There can be various language means for specifying
Critical Region, and one of them is the `synchronized' keyword.
However, it is not about the keyword, since you can call it
`synchronized', `region', `cr', or whatever. The main issue is that if
it is a language level means, it has consequences, see the semantics.
One important semantical issue is that the block marked by this
keyword may contain access to shared variables and access to shared
variables can only appear in these kind of blocks. Note that the low
level mutex can be inserted by the compiler to implement the Critical
Region defined at the language level. On the other hand, the high
level Critical Region can be implemented by any other means in the
compiler as far as it ensures mutual exclusion. That is one of the
benefit of a high level language.

2) In procedural languages if you introduce a keyword for a Critical
Region, you must also give some means to associate which shared
variables are involved. So, fixing your example, if there is a shared
resource `m' you can define a critical region using a keyword like
`synchronized' such as this:

shared int m; // the `shared' keyword marks the shared variable
...
synchronized(m) {
// here you can access `m'
}

Now the compiler can make sure that `m' is accessed within Critical
Regions and only within Critical Regions.

Can you see the difference between the language level means and the
library level means?

3) In object-based or higher level object-oriented languages the unit
of shared resource is obviously an object. So the association of the
Critical Region and the critical resource is naturally merged in an
object. That was one of the failure of Java that they were not brave
enough to mark the class as the shared resource. In a decent
concurrent object-oriented language you could specify a keyword for
the class to mark a shared object (and not for the methods). E.g.:

synchronized class M {
int m;
public:
void foo() {
// do something with `m' in mutual exclusion
}
};

You must mark the class as a whole and not the individual methods of
it. Then the compiler can again help you to make correct concurrent
programs. This is again not possible with library-based solution.

Note 1: We were talking about language level means for Critical Region
only but a concurrent language must provide means for Conditional
Critical Region as well. See also:
http://groups.google.com/group/comp.lang.c++/msg/041b2d8d13869371

Note 2: There is an important issue of defining threads of computation
at the language level, and the object-oriented solution for it is
indicated in the title of this discussion thread: "What's the
connection between objects and threads?" See also:
http://groups.google.com/group/comp.lang.c++/msg/4499fb9fb8c3a42a

Best Regards,
Szabolcs

I V

unread,
May 20, 2008, 8:26:54 PM5/20/08
to
On Tue, 20 May 2008 16:34:04 -0700, Szabolcs Ferenczi wrote:
> 2) In procedural languages if you introduce a keyword for a Critical
> Region, you must also give some means to associate which shared
> variables are involved. So, fixing your example, if there is a shared
> resource `m' you can define a critical region using a keyword like
> `synchronized' such as this:
>
> shared int m; // the `shared' keyword marks the shared variable ...
> synchronized(m) {
> // here you can access `m'
> }
>
> Now the compiler can make sure that `m' is accessed within Critical
> Regions and only within Critical Regions.
>
> Can you see the difference between the language level means and the
> library level means?

Lets imagine, instead of your syntax, we use this syntax:

shared<int> m;

{
synchronized<int> s(m);
// Here you can access the shared int 'm' through the object 's'
}

Again, the compiler can ensure that the shared state is only accessed
within a critical region (which, in this case, is equivalent to a block
containing the construction of the relevant synchronized<T> object). But
my proposed syntax can be implemented just as well with a library
solution as with a keyword based one, if the language provides certain
guarantees. So what's the difference?

Szabolcs Ferenczi

unread,
May 20, 2008, 8:56:10 PM5/20/08
to

It is not about syntax but first of all it is about semantics.
However, without syntax you cannot talk about semantics.

In your version `shared' and `synchronized' are keywords, aren't
they?

If yes, you already introduced keywords for the language which the
compiler can recognise. How would you describe the semantics of these
keywords? What is the role of object `s'?

If not, it can really be implemented with a library solution but the
compiler will not be able to identify the block what you mean as the
Critical Region and hence it cannot ensure for you that the intended
shared variable is only accessed within Critical Region.

Is it clear to you?

(Note that the role of "object 's'" is not clear in your proposal, see
"the shared int 'm' through the object 's'".)

Best Regards,
Szabolcs

co...@mailvault.com

unread,
May 20, 2008, 9:20:01 PM5/20/08
to
On May 20, 5:34 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:


I'm not sure marking the class like that is a good idea. Would you
mark vector as synchronized? If yes, do you expect compilers to
figure
out that only one thread is able to access some of your vector objects
at
any point in time and disable the synchronization? I don't want to
pay for
extra synchronization when it isn't needed.

Brian Wood
Ebenezer Enterprises
www.webEbenezer.net

I V

unread,
May 20, 2008, 9:31:27 PM5/20/08
to
On Tue, 20 May 2008 17:56:10 -0700, Szabolcs Ferenczi wrote:
> On May 21, 2:26 am, I V <ivle...@gmail.com> wrote:
>> Again, the compiler can ensure that the shared state is only accessed
>> within a critical region (which, in this case, is equivalent to a block
>> containing the construction of the relevant synchronized<T> object).
>> But my proposed syntax can be implemented just as well with a library
>> solution as with a keyword based one, if the language provides certain
>> guarantees. So what's the difference?
>
> It is not about syntax but first of all it is about semantics. However,
> without syntax you cannot talk about semantics.

Sure; I was trying to show you that you could get identical semantics to
the ones in your example using the existing C++ syntax (clearly, you need
more semantics than the C++ standard currently specifies; but the point
is that you don't need any more syntax).

> In your version `shared' and `synchronized' are keywords, aren't they?

They don't have to be, that's the point. They could be class templates.

> If yes, you already introduced keywords for the language which the
> compiler can recognise. How would you describe the semantics of these
> keywords? What is the role of object `s'?

With your suggestion, you declare the shared int 'm', synchronize on that
variable 'm', and access the shared data through the object 'm'. In my
suggestion, you declare the shared int 'm' and synchronize on the
variable 'm', but you access the shared data through the variable 's'.

The object of type synchronized<T> provides access to shared data of type
T that was declared with shared<T>. When an object of type
synchronized<T> is created, it ensures (through whatever method - the
obvious one is a mutex) that any other attempt to created a
synchronized<T> based on the particular shared variable will block. When
the synchronized<T> is destroyed, it removes that restriction.

> If not, it can really be implemented with a library solution but the
> compiler will not be able to identify the block what you mean as the
> Critical Region and hence it cannot ensure for you that the intended
> shared variable is only accessed within Critical Region.

Sure it can. The point is that the object of type synchronized<T> is the
only way in which one can gain access to the shared data. Therefore,
anywhere in which an object of type synchronized<T> is in scope is a
critical region; any attempt to access the shared state without creating
a synchronized<T> object (and therefore a critical region) will cause a
compile error. For instance:


shared<int> i, j, k;
i = j + k;

wouldn't compile, whereas:

shared<int> i, j, k;
{
synchronized<int> s_i(i), s_j(j), s_k(k);
s_i = s_j + s_k
}

would.

Chris Thomasson

unread,
May 20, 2008, 10:06:02 PM5/20/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:edfabf5f-0184-4fa8...@d45g2000hsc.googlegroups.com...
On May 19, 5:16 am, Ian Collins <ian-n...@hotmail.com> wrote:
[...]


> So, where are the incomplete objects after all?

> Earlier you said: "All I claim is that launching a thread in a
> constructor invokes undefined behaviour. Nothing more, nothing less."
> http://groups.google.com/group/comp.lang.c++/msg/856389deef6a40c0

> Please prove that claim of yours. Nothing more, nothing less. Where is
> the undefined behaviour?

I already showed a code example.

Chris Thomasson

unread,
May 20, 2008, 10:07:54 PM5/20/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:bd7dfdff-c6d5-49f3...@a1g2000hsb.googlegroups.com...

> On May 19, 8:54 am, "Chris Thomasson" <cris...@comcast.net> wrote:
> > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
> >
> > news:f99c4d57-48cd-4623...@2g2000hsn.googlegroups.com...
> > On May 18, 3:23 pm, James Kanze <james.ka...@gmail.com> wrote:
> >
> > > > Except that, as Chris has already pointed out, it results in a
> > > > race condition. It's a serious design error.
> > > 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.
> >
> > The pseudo-code I post over on 'comp.programming.threads' is all about
> > the
> > __experimental__ synchronization algorihtms that I am brainstorming. We
> > have
> > been over this before Szabolcs. If I come up with an idea, I try to make
> > sure to post it on c.p.t. If there is a typo in the pseudo-code, I
> > promptly
> > document them and show the corrections. Anyway...
> >
> > > You better read carefully what I have written. I highlighted that one
> > > needs discipline for it. It is hopless for you but at least you calm
> > > down.
> > > I hope I could help though.
> >
> > Unfortunately, wrt this thread, your so-called help is only going to
> > lead
> > the OP down the wrong path. You don't seem to get it. AFAICT, the OP
> > wanted
> > to create a thread base class for users to derive from. Something like:
> > ____________________________________________________________________
> [...]
> > ____________________________________________________________________
> >
> > The above demonstrates ...

> Well, the above demonstrates that a hacker can misuse any formal
> system.

The above demonstrates one reason why its generally NOT a good idea to start
threads in ctors.


> Kurt Goedel can be very pleased now up there since slaves are working
> for him down here.

> Congratulations!

Huh?

Chris Thomasson

unread,
May 20, 2008, 10:10:48 PM5/20/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:412b63f1-4e96-4520...@24g2000hsh.googlegroups.com...

> On May 19, 9:13 am, "Chris Thomasson" <cris...@comcast.net> wrote:
> > "Szabolcs Ferenczi" <szabolcs.feren...@gmail.com> wrote in message
> >
> > news:53d7b28a-337b-4b8c...@a1g2000hsb.googlegroups.com...
> > On May 18, 11:43 am, darren <minof...@gmail.com> wrote:
> >
> > > > 3. A successful accepted connection is put into a queue (from the
> > > > STL
> > > > library).
> > > > 4. Meanwhile, back at the ranch, another thread is created and
> > > > running
> > > > that continuously checks for entries into the queue.
> > > Be aware that although STL is thread-safe to a certain extent,
> >
> > Where does the current C++ standard say that the STL is "thread-safe to
> > a
> > certain extent"???

> For instance here:
> "The SGI implementation of STL is thread-safe only in the sense that
> simultaneous accesses to distinct containers are safe, and
> simultaneous read accesses to to shared containers are safe. If
> multiple threads access a single container, and at least one thread

> may potentially write, then the user is responsible for ensuring


> mutual exclusion between the threads during the container accesses. "

> http://www.sgi.com/tech/stl/thread_safety.html

I specifically asked about the C++ Standard. I am really not interested in a
particular vendors implementation. Try again...

Chris Thomasson

unread,
May 21, 2008, 12:16:21 AM5/21/08
to

"gpderetta" <gpde...@gmail.com> wrote in message
news:be607099-3736-4334...@u6g2000prc.googlegroups.com...
[...]

Well, at this point, IMVHO, Szabolcs has rendered himself into a complete
troll with no intention on learning anything. He even called David Butenhof
a fool for patiently trying to explain to him that condvars can be used to
signal about events that result from state mutations. Szabolcs makes an
assertion on comp.programming.threads that condvars CANNOT be used to signal
events; David Butenhof comes to his aid and tries to educate him, and ends
up getting called a fool... AFAICT, Szabolcs does not get it. Or, he does
not want to get it... Or, perhaps he does get it, and enjoys making an a$s
out of himself anyway. I am not entirely sure which one is correct...

I agree with James Kanze in that there should be a correcting response to
Szabolcs misleading and/or complete false claims just for the sake of some
newbie that might be mislead...

:^/

Chris Thomasson

unread,
May 21, 2008, 12:29:50 AM5/21/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:74f85a77-3a15-486d...@f63g2000hsf.googlegroups.com...

> On May 19, 11:50 am, James Kanze <james.ka...@gmail.com> wrote:
>> On May 18, 11:00 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
>> wrote:
>>
>> > On May 18, 9:59 pm, James Kanze <james.ka...@gmail.com> wrote:
>> > > On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
>> > > wrote:
>> > > > On May 18, 3:56 pm, James Kanze <james.ka...@gmail.com> wrote:
>> > > ...
>> > > 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 I'm one of the experts in the French national body, yes.
>> I'm very much aware about what is going into the standard.
>
> Very well. That explains a lot about the French contribution.

[...]

That's it... Insult an entire nation! Wow.


> You like to talk big, don't you.

IMVHO, James Kanze gives great advise. However, you seem to "enjoy" talking
down to experienced people from a position of high "ignorance". Sorry, but
that's the way you come across Sir.

:^|

Ian Collins

unread,
May 21, 2008, 12:30:28 AM5/21/08
to
Chris Thomasson wrote:
>
> Well, at this point, IMVHO, Szabolcs has rendered himself into a
> complete troll with no intention on learning anything.

Yet we still keep feeding him...

> He even called
> David Butenhof a fool for patiently trying to explain to him that
> condvars can be used to signal about events that result from state
> mutations.

Now that was a classic. The put down was even better:

http://tinyurl.com/5wk4l6

I should have learned my lesson there.

--
Ian Collins.

Chris Thomasson

unread,
May 21, 2008, 12:39:53 AM5/21/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:de295e38-abd6-4ef4...@t54g2000hsg.googlegroups.com...
> On May 19, 1:41 am, Ian Collins <ian-n...@hotmail.com> wrote:
> > Szabolcs Ferenczi wrote:
> >
> > > What is your problem exactly? It would be good, if instead of trolling
> > > you would prove something finally.
> >
> > I see your true colours have finally come through, insult all who
> > disagree with you.

> I try to get some proof out of you instead of you keep trolling.

> Besides, I new you would escape instead of proving your claims. It is
> the nature of trollers.

Ian already tried to patiently explain why running threads from ctors can be
a bad idea. I even gave you some code which shows how undefined behavior
results when a pure virtual function is invoked from the ctor of a base
class! Why is that so hard to understand Szabolcs? Did you know that the OP
was thinking about creating a thread object that was going to be used as a
base class? Your comment which suggested that creating threads in ctors is
okay was down right dangerous when you take the OP's question into account!
Why do you get angry when somebody points out one of your mistakes? You
should be thanking them for taking the time to do so!

Chris Thomasson

unread,
May 21, 2008, 12:41:15 AM5/21/08
to
"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:ab37efbb-fac2-46eb...@56g2000hsm.googlegroups.com...

On May 19, 6:42 am, Rolf Magnus <ramag...@t-online.de> wrote:

> > Yes. Copying a process with fork() is very fast. You don't get much of a
> > performance boost from using threads.

> Did you ever hear about heavy weight and light weight processes? I am
> just curious.

Name a platform?

It is loading more messages.
0 new messages