Posix thread exiting and destructors

G

Gianni Mariani

James said:
....

That's a separate issue. (In some cases, there's no need for a
clean shutdown anyway. A shutdown is, by definition, unclean.)

The C++ does describe how a shutdown works. How is it unclean ?
I think you're confusing the "thread" object with what the OS
considers a thread. In fact, the "thread" object, here, is just
a functional object which is called by the function whose
address is passed to pthread_create. The OS knows nothing about
it, and there's not the slightest problem with deleting it in
any thread you chose, as long as you are sure that no other
thread will use it. (In every case where I've used this idiom,
no other thread has even had a pointer to this object, so no
other thread could use it.)

I think I know what I meant. I have developed many heavily threaded
applications with C++ and my experience is that if you don't look after
shutting down, you will run into issues. The nastiest and most
difficult to debug is when you get an exception and the debugger points
to an empty page of memory. This usually happends when a thread is
executing some library code and some destructor is unloading a library
out from underneath another thread. While not impossible to debug, it
takes alot of repeated attempts to find which thread it is. Invariably,
the solution is to wait for the thread to complete before shutting down.

Exit is a special case, and needs to be handled, but it has no
relevance here.

Special in what way ? Like strcpy does not check for the size of the
destination or sprintf buffer overruns are not important until you find
that 2/3 of the computers on the net are bots ?
....
In at least one of the models being considered for
standardization, a thread IS an asynchronous function (which
possibly returns a type which can be used to get its return
value later).

I assume you mean the "future" interfaces ? It's of limited value IMHO.
It can't be used to implement most of the applications I have
implemented. There was a project where we did try to use it a few years
ago and I think it didn't prove a rich enough interface.
 
J

James Kanze

The C++ does describe how a shutdown works. How is it unclean ?

I expressed myself poorly. What I meant is that many
applications are meant to run "forever", and that the fact that
they are not (they are shutting down) means that something wrong
("unclean") has occurred.

I'm generally sceptical of this attitude, and prefer to provide
a mechanism for a clean shutdown even in programs designed to
run forever, but I've seen a lot of servers which can only be
stopped by "kill -9", or something similar.

(And of course, C++ doesn't really describe how shutdown works
in every case. It partially describes what happens if you call
exit() in a single threaded program, but it doesn't say
anything---yet---about threads, nor about what happens if the
process is the target of a "kill -9".)
I think I know what I meant.

Then why did you say something else?
I have developed many heavily threaded
applications with C++ and my experience is that if you don't look after
shutting down, you will run into issues.

If you provide a clean shutdown. If you don't provide a clean
shutdown, and require a "kill -9" to stop the process, then you
don't run into those issues. (You may run into others; it all
depends on what you are doing.)
The nastiest and most
difficult to debug is when you get an exception and the debugger points
to an empty page of memory.
This usually happends when a thread is
executing some library code and some destructor is unloading a library
out from underneath another thread.

That's really independant of shutdown, I'd say. Pull the rug
out from under a thread, and you're going to have problems.
Destructing an object in one thread that another thread is using
isn't a good idea, regardless of where it happens.
While not impossible to debug, it
takes alot of repeated attempts to find which thread it is. Invariably,
the solution is to wait for the thread to complete before shutting down.

No disagreement, really, but that has nothing to do with the
discussion at hand, and wasn't what you said before. In fact,
destructing the thread object in the thread, and not from
another thread, is probably the surest way of ensuring that the
object isn't destructed while the thread is still using it.
Special in what way ?

In that you don't expect to continue running, or handling
further requests, once it has been called. In that it will
never be called in a lot of servers.
Like strcpy does not check for the size of the
destination or sprintf buffer overruns are not important until you find
that 2/3 of the computers on the net are bots ?
I assume you mean the "future" interfaces ?
Yes.

It's of limited value IMHO.

It depends on what you are using threads for. For my
applications, it's not very useful, no. In fact, my threads are
normally detached; they correspond more to a void function which
executes asynchronously.
 
G

Gianni Mariani

James said:
....


It depends on what you are using threads for. For my
applications, it's not very useful, no. In fact, my threads are
normally detached; they correspond more to a void function which
executes asynchronously.

Invariably I find myself needing many of these "things" in one process
space for various reasons ranging from stress tests to scaling. The so
called short cuts to not design a consistant shutdown cause more
problems than it's worth. Server designs that appear like simple
classes so the objects can be created and destroyed at whim make for
very stable systems and easily embeddable in all kinds of ways. It's
kind of hard to kill -9 the object.
 
B

bjeremy

Boltar said:
I would have multiplexed , but each connection will be sending lots of
data and I waws concerned about write blocks. Just because the
select() mask flag says the socket is ready to write doesn't mean
it'll accept everything you throw. With multiplexing every socket
would have to be non blocking so a blocked socket doesn't hang every
other session and I'd have to keep tabs of retries etc. With threads
I can just let a socket happily block and it won't affect anything
else.

On a single processor, with using multiple threads to handle your
connections, the effect is a lot of context switching. And using
blocking I/O (opposed to non-blocking io) is also another unecessay
bottleneck that would slow down you server. If your design allows for
it, you may want to use seperate send and receive sockets... but I
understand that not every design can do this, depending on your
application.. With sends, you would just send the data, and if you
catch a signal, just re-try the send.. don't even bother keeping track
of re-tries.
Anyway, I don't have the books in front of me at the moment, but
Stevens, "Unix Network Programming vol 1", talks about different
server types and their pros and cons... also there is a good
discussion about performance of different server tyoes in this
O'reilly book "Java Network Programming"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top