Boost logo

Boost :

From: Ninel Evol (myLC_at_[hidden])
Date: 2007-07-08 14:26:39


Sorry, I'm a little late - here goes:

Anthony Williams wrote:

> The current C++0x thread library proposal (http://www.open-
> std.org/jtc1/sc22/wg21/docs/papers/2007/n2320.html) includes
> request_cancellation(), which requests a thread cancel at
> the next call to cancellation_point() or one of the standard
> cancellation points (such as waiting on a condition
> variable). I intend to add this facility to Boost.thread
> once the move to subversion is complete.

Yes - and it's useful. I would like to see both possibili-
ties! The cancellation by "polling" is most useful when
writing server- or lib-code. A GUI friendly approach has to
be different however.
If you have to poll anyway - why go through all the thread
trouble anyhow - just poll the GUI event loop instead.
Creating worker threads is usually done for convenience.
Polling is inconvenient.

I read the proposal. One thing that stroke me was the list
of recommended cancellation points. They all somehow imply
that the thread is already "on hold" (if not polling).
Let's look at real life examples:
1. You have an editor or whatever application; the user has
   selected a file that is to be read in. For convenience,
   the reading takes place in a background thread. The user
   has the possibility to cancel the operation.
   Suppose the file is large and being read over a dead
   slow NFS connection. So (s)he chooses to cancel.
   Where is you cancellation point in there?
   Is the application supposed to get stuck (as many do)?
2. The classical worker thread pattern:
   You have a really tight loop computing something. You
   just don't want to poll in there as it hurts. The com-
   pare operation for checking out of the loop every once
   in a while already costs too much. What do you do?
   Currently only "dirty killing" is what I could think of
   and that usually means that you have to do the cleanup
   in the main thread (not object-oriented).

Those patterns can be found in many (if not the majority) of
GUI applications. Sure, you can write around it (see Qt) -
but that's rather ugly coding...

> This is very messy --- it's asynchronous, so will break all
> sorts of stuff. POSIX asynchronous thread cancellation has
> successfully demonstrated that it's a bad idea, except for
> very specific cases.

Posix' threads came late - too late. And as usual they
didn't really go for a "pragmatic approach". The old saying:
"Posix is better than nothing".

I agree that it's a bit messy behind the scenes. However,
you can have it the easy way. If you put the thread to sleep
first - your patient is in a coma; operating on it is not so
tricky then. That was only a bare example, you can of course
synchronize it (and you might want to do that in many
cases;o).

Again, let's take a look at an example:
A trickier one - cancellation while retaining data:
For example the application has computed for hours and you
want to abort the operation and let it finish tomorrow 'coz
you need to phone ant Hermine and you only have one line...
Silly code example:

// either declared in the object or on the heap:
map< BigUInt, answer_type > *war_dial;

// then in the thread you have to put those
// critical accesses within a "critical section":
noAbortBegin();
        war_dial[ number ] = answer;
noAbortEnd();

// or for the forgetful as an object:
{
        noAbort na;
        war_dial[ number ] = answer;
}

Behind the scenes this basically increments an atomic
variable (check and set). So if you have a cancellation
request from another thread (say the main thread), the
worker thread is put to sleep. Then the no-abort variable is
checked, if not zero a flag is set to indicate to the thread
to throw an abort-request itself the next time it ends a
"critical section" and the counter is zero (nesting).
If the no-abort is unchecked (count of zero) you can fix the
instruction pointer to let the thread throw an abort-request
when it wakes up. Then you wake the sleeping thread and
either wait for it to die, wait with a timeout - or (in case
it's all on the heap) simply not care anymore. For the
latter you have to make sure not to leave any children
running while the parents go dead of course...

Very much like C++ exceptions this is not that efficient.
It's meant for exceptions - and only exceptions. "Abort
requested by user" is one of those (and a very common one
too). So I would still like to see both approaches
implemented (they complement one another).

The possibility to cause an exception within a thread no
matter what operation it's doing is very powerful. Asking a
programmer to protect critical accesses on persistent
data/objects with "critical sections" if using that feature
is not too much (and incrementing a variable is rather cheap
as well).

Hope I don't seem to stubborn about this, but I really think
that once it would be there C++/C-0x programmers wouldn't want
to miss such a feature anymore.

--- about wx:

Scott McMurray wrote:

> > I read that some folks thought about the wxWidgets and the
> > Boost (C-0x) team joining forces.
> > I think that would be a marvelous idea!
>
> I think they'd come to blows, given how reluctant wx seems
> to be to use any feature added to C++ in the past 17 years
> or so :|
>
> I don't think that's an ezaggeration, either. Have you
> looked at the wx developer guidelines lately? Looks like
> they want nothing from after the ARM...

Hahaha, yes - arrays, maps and the like as preprocessor
macros... also when it comes to posting bug reports it seems
very much like someone there is "running a camp"! X-O

It is supposed to be about "backward compatibility" with
some compilers from the Jurassic period.
However, it looks as if "they" intent to start over with
version 3.

C-0x is going to end up in the same swamp as C++ without a
useable GUI support. Sure, you can have second party
libraries. But then you also need support for the second
party libs (like GUI builders, usually not integrated) and
the swamp sets in deep when debugging non-native objects.
"Do it by hand Luke"...
Like this, C-0x won't stand a chance against free all-in-one
Java or C# (reads: "C crooked") alternatives (not that I
would use them - coming from the Assembler countries).

Despite the reasonable disbelieves I think that there should
be a debate with the wx folks. The problem with C-0x seems
to be a lack of resources for something as complex as a
proper GUI support. With the wx team maybe willing to start
all over (they certainly didn't do a bad job!) joining forces
could bring C-0x to new highs.
It's worth a try, someone cast the first stone PLEASE! :-)

> ... Last I looked, gtkmm was the closest to providing C++-
> style interfaces and such, so maybe there's hope.

Hmmm... I think the mingw part is somewhat chasing away
programmers and the last time I looked into gtkmm it read
"TODO" almost everywhere...
Same problem as C-0x it seems. ;-{

> Unfortunately, http://www.omgui.org/, which was trying for a
> real C++ GUI lib, seems rather dead.

Lack of resources - how I hate this song...

> The STL is also quite useful, all by itself. I'm using it
> heavily in my research. I have no use for GUIs or sockets.
> I tried threads, but my bottlenecks are all I/O, so they
> don't make a difference. I do most of my the output to
> console, with some OpenGL for visualization. No QT, wx, or
> other ancient frameworks needed, nor would they be helpful.

If the bottlenecks are all I/O then the STL (iostreams in
particular) could be one of them. If I recall it correctly
the STL was a lot slower than the C counterparts in that
area. X-|

Well, that's it from me - gotta puff up my belly...

Regards,
                                            LC (myLC_at_[hidden])

-- 
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kanns mit allen: http://www.gmx.net/de/go/multimessenger

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk