By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,241 Members | 799 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,241 IT Pros & Developers. It's quick & easy.

What's the connection between objects and threads?

P: n/a
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
Jun 27 '08 #1
Share this Question
Share on Google+
167 Replies


P: n/a
darren 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.
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.
Jun 27 '08 #2

P: n/a
darren <mi******@gmail.comwrote in news:7083eb1a-4dbd-4b94-866b-
fd**********@c19g2000prf.googlegroups.com:
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
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

Jun 27 '08 #3

P: n/a
On May 17, 10:20*pm, darren <minof...@gmail.comwrote:

"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
Jun 27 '08 #4

P: n/a
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.
Jun 27 '08 #5

P: n/a
"darren" <mi******@gmail.comwrote in message
news:3e**********************************@d19g2000 prm.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....9b2ce54349af0f
(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 <ENTERto exit...");
std::getchar();
return 0;
}

__________________________________________________ __________________

Any questions?

Jun 27 '08 #6

P: n/a
On May 17, 8:35 pm, "Chris Thomasson" <cris...@comcast.netwrote:
"darren" <minof...@gmail.comwrote in message

news:3e**********************************@d19g2000 prm.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..../browse_frm/th...
(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 <ENTERto exit...");
std::getchar();
return 0;

}

__________________________________________________ __________________

Any questions?
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.
Jun 27 '08 #7

P: n/a
On May 18, 3:24 am, darren <minof...@gmail.comwrote:
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.
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...
Jun 27 '08 #8

P: n/a
On May 18, 1:13 am, ManicQin <Manic...@gmail.comwrote:
On May 18, 3:24 am, darren <minof...@gmail.comwrote:
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.

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

Jun 27 '08 #9

P: n/a
On May 18, 11:43*am, darren <minof...@gmail.comwrote:
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
Jun 27 '08 #10

P: n/a
On May 18, 11:43*am, darren <minof...@gmail.comwrote:
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
Jun 27 '08 #11

P: n/a
On May 18, 2:24*am, darren <minof...@gmail.comwrote:
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
Jun 27 '08 #12

P: n/a
On May 18, 11:43*am, darren <minof...@gmail.comwrote:
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
Jun 27 '08 #13

P: n/a
On May 18, 12:43 pm, darren <minof...@gmail.comwrote:
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.
Jun 27 '08 #14

P: n/a
On May 18, 11:43*am, darren <minof...@gmail.comwrote:
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
Jun 27 '08 #15

P: n/a
On 18 mai, 12:44, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:
On May 18, 11:43 am, darren <minof...@gmail.comwrote:
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:ja*********@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
Jun 27 '08 #16

P: n/a
On 18 mai, 13:29, ManicQin <Manic...@gmail.comwrote:
On May 18, 12:43 pm, darren <minof...@gmail.comwrote:
[...]
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.

--
James Kanze (GABI Software) email:ja*********@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
Jun 27 '08 #17

P: n/a
On May 18, 3:23*pm, James Kanze <james.ka...@gmail.comwrote:
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
Jun 27 '08 #18

P: n/a
On May 18, 3:27*pm, James Kanze <james.ka...@gmail.comwrote:
On 18 mai, 13:29, ManicQin <Manic...@gmail.comwrote:
On May 18, 12:43 pm, darren <minof...@gmail.comwrote:

* * [...]
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
Jun 27 '08 #19

P: n/a
On 18 mai, 11:43, darren <minof...@gmail.comwrote:
On May 18, 1:13 am, ManicQin <Manic...@gmail.comwrote:
[...]
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 (GABI Software) email:ja*********@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
Jun 27 '08 #20

P: n/a
On 18 mai, 11:43, darren <minof...@gmail.comwrote:
On May 18, 1:13 am, ManicQin <Manic...@gmail.comwrote:
[...]
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 (GABI Software) email:ja*********@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
Jun 27 '08 #21

P: n/a
On May 18, 4:56 pm, James Kanze <james.ka...@gmail.comwrote:
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!!!)
Jun 27 '08 #22

P: n/a
On 18 mai, 17:06, ManicQin <Manic...@gmail.comwrote:
On May 18, 4:56 pm, James Kanze <james.ka...@gmail.comwrote:
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.

--
James Kanze (GABI Software) email:ja*********@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
Jun 27 '08 #23

P: n/a
On May 18, 3:56*pm, James Kanze <james.ka...@gmail.comwrote:
On 18 mai, 11:43, darren <minof...@gmail.comwrote:
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....13d1c864883be3)
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
Jun 27 '08 #24

P: n/a
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.
Jun 27 '08 #25

P: n/a
On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:
On May 18, 3:56 pm, James Kanze <james.ka...@gmail.comwrote:
On 18 mai, 11:43, darren <minof...@gmail.comwrote:
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....13d1c864883be3)
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 (GABI Software) email:ja*********@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
Jun 27 '08 #26

P: n/a
On 18 mai, 21:08, darren <minof...@gmail.comwrote:
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.)

--
James Kanze (GABI Software) email:ja*********@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
Jun 27 '08 #27

P: n/a
Szabolcs Ferenczi wrote:
On May 18, 3:23 pm, James Kanze <james.ka...@gmail.comwrote:
>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.
Jun 27 '08 #28

P: n/a
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.
Jun 27 '08 #29

P: n/a
On May 18, 9:59*pm, James Kanze <james.ka...@gmail.comwrote:
On 18 mai, 18:22, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:
On May 18, 3:56 pm, James Kanze <james.ka...@gmail.comwrote:
...
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
Jun 27 '08 #30

P: n/a
On May 18, 10:41*pm, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 18, 3:23 pm, James Kanze <james.ka...@gmail.comwrote:
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
Jun 27 '08 #31

P: n/a
Szabolcs Ferenczi wrote:
On May 18, 10:41 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Szabolcs Ferenczi wrote:
>>On May 18, 3:23 pm, James Kanze <james.ka...@gmail.comwrote:
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.
Jun 27 '08 #32

P: n/a
On May 18, 11:24*pm, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 18, 10:41 pm, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 18, 3:23 pm, James Kanze <james.ka...@gmail.comwrote:
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.
Right. And now please read carefully what I have written in this
thread about this issue.

Best Regards,
Szabolcs
Jun 27 '08 #33

P: n/a
Szabolcs Ferenczi wrote:
On May 18, 11:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
>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.

--
Ian Collins.
Jun 27 '08 #34

P: n/a
darren wrote:
On May 17, 8:35 pm, "Chris Thomasson" <cris...@comcast.netwrote:

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.
Jun 27 '08 #35

P: n/a
On May 18, 11:58*pm, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 18, 11:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
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:

"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....13d1c864883be3

"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....0fdce805e9f407

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.
Jun 27 '08 #36

P: n/a
Szabolcs Ferenczi wrote:
On May 18, 11:58 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Szabolcs Ferenczi wrote:
>>On May 18, 11:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
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.
Jun 27 '08 #37

P: n/a
On May 19, 12:19*am, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 18, 11:58 pm, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 18, 11:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
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.
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.
Jun 27 '08 #38

P: n/a
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.
Jun 27 '08 #39

P: n/a
Szabolcs Ferenczi wrote:
On May 19, 12:19 am, Ian Collins <ian-n...@hotmail.comwrote:
>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.
Jun 27 '08 #40

P: n/a
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.
Jun 27 '08 #41

P: n/a
On May 19, 12:48*am, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 19, 12:19 am, Ian Collins <ian-n...@hotmail.comwrote:
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.

I am looking forward to your demonstration.

Best Regards,
Szabolcs
Jun 27 '08 #42

P: n/a
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.
Jun 27 '08 #43

P: n/a
On May 19, 12:48*am, Ian Collins <ian-n...@hotmail.comwrote:
Szabolcs Ferenczi wrote:
On May 19, 12:19 am, Ian Collins <ian-n...@hotmail.comwrote:
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
Jun 27 '08 #44

P: n/a
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.
Jun 27 '08 #45

P: n/a
On May 19, 1:25*am, Ian Collins <ian-n...@hotmail.comwrote:
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
Jun 27 '08 #46

P: n/a
On May 19, 1:41*am, Ian Collins <ian-n...@hotmail.comwrote:
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.

Best Regards,
Szabolcs
Jun 27 '08 #47

P: n/a
Szabolcs Ferenczi wrote:
On May 19, 1:25 am, Ian Collins <ian-n...@hotmail.comwrote:
>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.
Jun 27 '08 #48

P: n/a
On May 19, 12:08*am, darren <minof...@gmail.comwrote:
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.
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.
Jun 27 '08 #49

P: n/a
ManicQin wrote:
On May 18, 4:56 pm, James Kanze <james.ka...@gmail.comwrote:
>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.
Jun 27 '08 #50

167 Replies

This discussion thread is closed

Replies have been disabled for this discussion.