The future of C++

K

Kevin Cline

Jim Melton said:
The CORBA C++ binding suffers from much of the same baggage as the C++
language: backward compatibility.
At the time the binding was specified,
there was no STL, consequently no std::string (one of the biggest disasters
of the binding). To change the binding now would break *all* existing
programs, so it will not be done lightly.

Binding is done by the IDL compiler with support from the marshalling
code. Why not define a modern C++ binding that could be selected when
the IDL is compiled?
 
M

Maciej Sobczak

Hi,

Jim said:
The CORBA C++ binding suffers from much of the same baggage as the C++
language: backward compatibility. At the time the binding was specified,
there was no STL, consequently no std::string (one of the biggest disasters
of the binding). To change the binding now would break *all* existing
programs, so it will not be done lightly.

I do not see any reason why there should be only *one* binding.
CORBA is used not only to maintain legacy systems, but also to write new
ones, where it does not really matter if the binding was defined 10
years ago or just a while ago. The "new" and "old" bindings could of
course interoperate over the wire, just like components in different
languages do. After all, the whole idea of binding is to decouple
components from the implementation details of each other.

Having the strings bound to std::string and arrays to STL sequences
would be beneficial to those who want to use CORBA in new systems. I do
not understand what is the merit of repeating this compatibility
argument over and over well 6 years after the C++ standard was set up.
 
T

Thomas Richter

Hi Jim,
Writing distributed programs is hard.

Gee, I know. I'm writing one.
If you have any doubt, just Google
this group for discussions on multi-threading. Distributed programming is
multi-threading with unknown latency and unreliable communication. It takes
more to write a distributed program than to just slap some middleware
between two programs you wrote. The CORBA spec represents 10 years of
experience with what is required to do distributed programming. The stuff
you don't think you need... you'll need it.

The point is not that "I think I don't need it, so drop it". The thing is
that the stuff I need is pretty elaborate already in fields where there's
absolutely no need for being so complex. Why's there no "layered" design
of the iterface so "I don't need to care about what I don't need to use".
The CORBA C++ binding suffers from much of the same baggage as the C++
language: backward compatibility. At the time the binding was specified,
there was no STL, consequently no std::string (one of the biggest disasters
of the binding). To change the binding now would break *all* existing
programs, so it will not be done lightly.

Of course. First, that doesn't make things better, of course. It only
explains the reasons. But what about offering an optional new binding
as an extension?
At the risk of straying even farther off-topic for this group, I'll point
out that Michi Henning has gone on to write a middleware designed to work
much more intuitively with C++, and has taken quite a bit of heat from,
among others, Steve Vinoski.

I've been following this discussion, actually. However, CORBA is pretty
much standard, it works, so I'm currently very reluctant to choose
something different (incompatible).
Again, this is off-topic for this group, and you might want to take these
comments to the CORBA group, but "mutex" has no tractable meaning in
distributed programming. CORBA specifies the interface by which clients may
access distributed services, and it defines language bindings by which
programmers may implement (or access) those services.

But whenever I implement a distributed program, it is very common that
need to consider the situation that several clients approach one server
at the same time, so I need to care about consistency very much so. I
would even go further and say that this is a pretty much central problem
in distributed software.

Ok, what about the following: I believe that the CORBA folks know quite
a lot about these problems, so what about setting up a list of features
that are generally considered "necessary" to implement a distributed
program. If the result will not be part of CORBA, it could become
part of C++ since synchronization problems are not only CORBA specific
but more general. I would really suggest that one knowledgable member
of the CORBA group approaches the C++ committee by ideas of how a
standard "distributed services" library should look like. If it also
contains threading and mutexes, it will be quite useful for everyone
else in C++.
I don't get the question.

No question. Just my answer. I agree.
From a CORBA programmer's perspective, a better
C++ binding would be desirable. But from a C++ programmer's perspective, why
should I care?

Well, even *if* you don't write CORBA, a library providing necessary services
for CORBA (and even though I'm far from an expert, I believe threads and
mutexes are essential for that) and for CORBA applications will help you a lot
in other situations. Plus, these are the people that should have the
experience in the field.
Why do you assume that CORBA will triumph over SOAP or EJB or
the next greatest fad in distributed programming?

I, personally? I don't know. I'm using it "because it works". If I also
get a SOAP or EJB implementation that is common enough to be found available
for Java, C++, C and various operating systems like Linux or Windows, I
could also use that.

So long,
Thomas
 
D

David Eng

Thomas Richter said:
Hi,



But then, CORBA *requires* the corresponding ORB/POA implementation to
provide threads one way or another, why doesn't it require from the
implementing library to provide some mutex mechanism as well? Or
rather, to make the internal locking mechanism any suitable
implementation must have anyhow available to the outside as a service?
Whether this should be part of C++ or not is another question, but it
should be definitely mandatory part of the CORBA specifications to
have. A specific implementation could still make use of a potential
"standard" mutex/threading class as soon as we had one.

The problem is if threads are specified by CORBA, the behavior of
implementation would be disaster. There is big different between a
thread library and a language that supports thread. In a thread
library, the lock and unlock must be called explicitly while they can
be called implicitly in a language with thread mode. In a distributed
environment, you cannot guarantee the unlock will be called
explicitly. What happen if an exception is thrown? Then the system
will locked for ever. If a language supports thread, the unlock will
be called implicitly in this situation. Since CORBA support multiple
languages and not every languages support thread. So, it is difficult
for CORBA to specify a thread mode. That's why I wonder why C++
standard doesn't have a thread standard. If a language doesn't
support thread, it will put huge burden on developers in multi-thread
applications since the compiler, processor, and memory system all can
alter the behavior of a multi-threaded applications.
 
S

Steven T. Hatton

Thomas said:
Whether this should be part of C++ or not is another question, but it
should be definitely mandatory part of the CORBA specifications to
have. A specific implementation could still make use of a potential
"standard" mutex/threading class as soon as we had one.


This is true to some degree, but is another argument.

So long,
Thomas

Has this been mentioned in this context? I know virtually nothing about it
other than Stroustrup mentions it in one of his web pages, and the
introductions I've read sound hopeful.

/*----------------------Excerpt------------------*/
Overview of ACE
The ADAPTIVE Communication Environment (ACE) is a freely available,
open-source object-oriented (OO) framework that implements many core
patterns for concurrent communication software. ACE provides a rich set of
reusable C++ wrapper facades and framework components that perform common
communication software tasks across a range of OS platforms. The
communication software tasks provided by ACE include event demultiplexing
and event handler dispatching, signal handling, service initialization,
interprocess communication, shared memory management, message routing,
dynamic (re)configuration of distributed services, concurrent execution and
synchronization.

ACE is targeted for developers of high-performance and real-time
communication services and applications. It simplifies the development of
OO network applications and services that utilize interprocess
communication, event demultiplexing, explicit dynamic linking, and
concurrency. In addition, ACE automates system configuration and
reconfiguration by dynamically linking services into applications at
run-time and executing these services in one or more processes or threads.

ACE continues to improve and its future is bright. ACE is supported
commercially via the Riverace corporation using an open-source business
model. In addition, many members of the ACE development team are currently
working on building The ACE ORB (TAO).
/*------------------END-Excerpt------------------*/

http://www.cs.wustl.edu/~schmidt/ACE-overview.html

http://www.awprofessional.com/title/0201604647

http://www.awprofessional.com/title/0201795256
 
D

David Eng

David Abrahams said:
We are moving to grid computing, yet C++
committee doesn't think it is important to standardize a thread
library.

Please. Did you submit a proposal for a standard threads library?
Did anyone? [hint: the answer is no]

The "C++ committee thinks" (as though we are all of one mind, but I'll
play along) that a threading library is important. I don't think we
have any threading experts with the time to bring forward a proposal
on it. If you think you're qualified, please do it yourself.

No! I don't think I am qualified, but that doesn't mean I cannot have
a opinion about thread. As a software engineer who make living by
writing code, I feel strongly C++ should supports thread, especially,
in a distributed environment. A thread library is different from a
language which supports thread. In a thread library, lock and unlock
must be called explicitly while they can be called implicitly in a
language that supports thread. The system will be deadlock if
something happens before the unlock is called explicitly in a thread
library. It will never happen if the language support thread because
the unlock will be called implicitly. Besides, you have to deal with
compiler, processor, and memory system if the language doesn't support
thread to write multi-thread applications. Furthermore, without a
standard thread, you have to use these proprietary thread libraries
which are hard to maintain and scale cross different platforms and
development environments. For all these reasons, C++ standard
committee shall consider next standard shall support thread.
 
K

kanze

Steven T. Hatton said:
David Eng wrote:
Is the problem that the committee doesn't think it's important, or is
it that the committee doesn't have the resources? What about
http://www.boost.org/libs/thread/doc/index.html? That seems to have
the unofficial blessing of the committee. I agree that C++ /seems/ a
bit behind the times when it comes to threading, and many other
issues. What about X509, and all the other crypto stuff. Take a look
at the standard Java SDK, and compare that to what you can get with a
'standard' C++ setup. I haven't looked at C#'s offerings, but I
gather it comes with a similar arsenal of libraries.

If not following every silly fad that comes along means being behind the
times, so be it. There is no particular reason to integrate everything
into the language standard; there are even several very good reasons not
to, if you want to remain a general purpose language, instead of
targetting just a few niches.
The [other] area bothers me is database access layer. All these
database vendors promote JDBC because there is no a standard C++
access library. If these vendors stop to support their proprietary
C++ API, who will use C++ in a distributed environment? I never
head C++ committee even has an initiative to standardize a database
access layer library.
There are many open source libraries available, and for that matter,
you could probably make a C++ to JDBC bridge. I suspect it's already
been done. Nonetheless, I agree that standards are a good thing. I
find myself spending a lot of time hunting around for solutions to
things I get as part of Java either with the JSDK or as a freely
available extension. And let us not forget XML.

For the equivalent of JDBC, there's always the OTL. I'm not sure that
it is the right solution: I have my doubts about ostreaming selection
parameters, and I haven't used it enough concretely to confirm or deny
them. But it looks like a good point to start discussions, and it
certainly does get the job done.

For the rest, I repeat: not everything belongs in a language standard.
Generally speaking, if you can implement it in standard C++, it only
belongs in a language standard if it is needed pretty universally:
std::vector, std::string or std::sort, for example. Otherwise, the
basic argument for is based on the fact that you cannot implement it, or
you cannot implement it efficiently, in standard C++. Threading
certainly qualifies, a data base bridge might. std::latest_in_format
doesn't. (Why XML, for example, and not BER encoded ASN.1? BER encoded
ASN.1 is probably more widely used, is certainly stabler, and has been
around a lot longer.)
I believe C++ has a lot of problems when it comes to competing with
Java and C#. People who have never coded in Java (I can't comment on
C# directly) really have no idea of the strengths Java has as far as
ease of use.

Java's fine for some things, especially if you are working in one of the
niches where it is specialized. It doesn't cut it if you need
reliability or safety, though, and it doesn't lend itself to large scale
programming, nor to system level programming. (You can't implement a
JVM in Java, for example. And I've done some large scale work in Java
to know of its weaknesses there.)
C++ _*needs*_ some kind of module support.

I think that there is a general consensus that textual inclusion is NOT
the ideal way of handling modules. Regretfully, there doesn't seem to
be much consensus as to what is the right way.
It probably also should have checked exceptions.

I agree, but I suspect that I am in a very small minority.

It's worth noting, too, that most Java developers systematically derive
from RunTimeException to avoid the checking. In practice, Java doesn't
really have checked exceptions -- it just pretends it does. (In
practice, Java seems to have found an interesting compromize: all the
pains of checked exceptions, without any of the advantages.)
I have the sense many C++ programmers don't really understand the
concepts of listeners and events as they are used commonly in Java.

What makes you think this? I seems like a commonly used idiom in C++.
And a lot safer in C++ than in Java, at least in the typical uses I've
seen. Generally speaking, to use it well, you need multiple
inheritance. Or at least some way of enforcing a contract for an
interface. On the other hand, of course, it is a lot easier to use if
you have garbage collection, but since it typically doesn't involve
cycles, and uses objects that make no sense other than on the heap, you
can get by reasonably well with invasive reference counting. You also
need some sort of type safe container to hold your listeners, and that
is (or was until very recently) seriously lacking in Java.
All one really needs to do is to pick up _The Java Programming
Language_, by Arnold, Gosling and Holmes, and read the first 10 or so
chapters to see how much Java offers as core features.

Actually, if you don't get beyond the first 10 or so chapters, you'll
find more of what is missing. Practically speaking, in fact, unless you
get to libraries or infrastructure, you'll really only encounter things
that are missing. Java, the language, has a very few advantages over
C++: it's easier to parse, if you need to write a parser, it has garbage
collection, and it has real arrays, that act like first class objects.
On the other hand, you don't have any scope dependant user defined
types, and so no destructors or other clean-up mechanism, you don't have
any possibility of writing type safe containers, listern mechanisms,
etc., the language pretty much forbids writing strict interfaces (no
programming by contract), it has strange rules for the resolution of
virtual functions, which means that you often end up in a virtual
function on an object that hasn't been constructed. You complained
about the fact that C++ uses textual inclusion to separate interface
from implementation; Java doesn't even allow the separation. The
absense of any possibility to use programming by contract pretty much
excludes the use of Java for critical systems, and the lack of
separation between the class definition and its implementation pretty
much means you can't use it on large projects.
Too often C++ programmers become defensive and dismissive of these
strengths of Java. If someone presents an I idea which even hints
that it may have been influence by java, it is automatically rejected.

Not at all. I've done some fairly large projects in Java, and at one
time, knew it at least as well as I know C++. The more I used it,
however, the more I realized that it simply wasn't appropriate for the
type of work I do (large scale servers), nor for the type of work I'd
done a lot of in the past (real time industrial systems and system level
programming). It would be my first choice for a web page server (based
on JSP), and despite all of the problems due to the lack of type safe
containers and multiple inheritance, I really liked Swing. But in both
cases, it isn't the language which is determinating, it is the
infrastructure or the library.
I've been putting a lot of time into C++ lately, and I know there are
significant strength in the language that Java lacks. But they may
not be sufficient to keep anything but a niche in the emerging
environment.

In which environment. There are certain environments in which C++ has
pratically disappeared (if it was ever present). They are very much in
view, but taken globally, I don't know if they represent that big of a
percentage of actual software.
One view I've seen expressed on usenet is that Sun, Microsoft, IBM,
Borland, etc., are a bunch of idiots for shifting their focus to Java
(or C#). There's not much to say to in response to such assertions.
They seem to speak for themselves.

Hmmm. Microsoft seems to have moved its focus from Java, and at least
for the moment, C# or not, seems to take the attitude that C++ will be
around for a long time as well, and has a place in their plans. Borland
seems to prefer Delphi. But that is neither here nor there. There is
definitly a market for the latest fad; it would be silly for any of the
above named companies to ignore it. Just as it would be silly for them
to put all of their eggs in the Java basket. IMHO, Microsoft seems to
have understood this, and is steering a middle ground. Sun seems to
have shot itself in the foot, not so much because it supported and
pushed Java, but because it forgot its bread and butter products (Unix
based workstations) in doing so. (Note that Microsoft hasn't slowed
down developments on Windows or MS-Office simply because they have C#.)
 
F

Frank Buss

A thread library is different from a
language which supports thread. In a thread library, lock and unlock
must be called explicitly while they can be called implicitly in a
language that supports thread. The system will be deadlock if
something happens before the unlock is called explicitly in a thread
library. It will never happen if the language support thread because
the unlock will be called implicitly.

Java supports threads, but you can have deadlocks even if the language
supports threads, but perhaps do you have ideas how the language can
avoid it? With functional languages like Haskell and Parallel Haskell it
would be easier, because there are no side-effects so the compiler can
parallelize the program without the need to program it explicit, but
deadlocks are still possible, if you want explicit synchronisation.
Besides, you have to deal with
compiler, processor, and memory system if the language doesn't support
thread to write multi-thread applications.

A standard library could hide it, like the STL library hides the
implementation details. I just can write vector<int> and don't need to
know anything about the memory system. The Boost library has cross
platform thread support:

http://www.boost.org/libs/thread/doc/index.html
 
K

kanze

(e-mail address removed) (David Eng) wrote in message
David Abrahams said:
(e-mail address removed) (David Eng) writes:
We are moving to grid computing, yet C++ committee doesn't think
it is important to standardize a thread library.
Please. Did you submit a proposal for a standard threads library?
Did anyone? [hint: the answer is no]
The "C++ committee thinks" (as though we are all of one mind, but
I'll play along) that a threading library is important. I don't
think we have any threading experts with the time to bring forward a
proposal on it. If you think you're qualified, please do it
yourself.
No! I don't think I am qualified, but that doesn't mean I cannot have
a opinion about thread. As a software engineer who make living by
writing code, I feel strongly C++ should supports thread, especially,
in a distributed environment. A thread library is different from a
language which supports thread. In a thread library, lock and unlock
must be called explicitly while they can be called implicitly in a
language that supports thread.

In the Boost threading library, I believe that lock and unlock are
private functions, which cannot be called explicitly. In no C++
threading library that I am familiar with is it necessary to call unlock
explicitly. On the other hand, there are significant cases where the
lock does not obey normal scoping rules; the locking mechanisms built
into languages like Java don't work in such cases, and require
significant complications to work around their limits.
The system will be deadlock if something happens before the unlock is
called explicitly in a thread library.

A deadlock can occur whether the locks are part of the language, or in a
separate library.
It will never happen if the language support thread because the unlock
will be called implicitly.

Only when you leave the scope in which the lock is held. Exactly as in
C++.
Besides, you have to deal with compiler, processor, and memory system
if the language doesn't support thread to write multi-thread
applications.

Memory synchronization issues is one reason why threading must be
treated at the language level. Things like initialization of local
statics is another. IMHO, the interface to the locking functions should
remain a library function.
 
K

kanze

And yet, Ada supports it as a built-in feature of
the language, in compilers which support the
Distributed Systems Annex E.

That doesn't mean that writing distributed programs isn't hard. It
might mean that if you want to do hard things, you need Ada:).

Seriously, I'm not sure what a language should do to support distributed
programming. The problem is that so many things that we do which have
negligible cost (for most people) don't have negligible cost when you
distribute. When the cost of calling a function goes up to 10-100
milliseconds, regardless of what you do in the function, you really have
to think about doing as much as possible, in a single function. If I'm
developping in C++, on a single machine, I won't hesitate to use getters
for each individual piece of data. If I'm working over a Corba
interface to a remote machine, however, I'll design a custom function:
getWhatINeed -- the server must know enough about me to send everything
in one go (in a specialized struct which contains everything that I
need, typed).
 
K

kanze

Frank Buss said:
(e-mail address removed) (David Eng) wrote:
[...]
Besides, you have to deal with
compiler, processor, and memory system if the language doesn't support
thread to write multi-thread applications.
A standard library could hide it, like the STL library hides the
implementation details.

Not completely. What happens if some of the generated code uses static
variables. An obvious candidate would be exception processing, and at
least one compiler I have used does fail if two threads throw an
exception at the same time.

Generally speaking, threading is a special case, because it must be
recognized by the basic language. Today, in the Unix world, we count on
compilers being not just standard C++ compliant, but also Posix
compliant (and Posix does recognize threads). It's a bit awkward, since
Posix compliance doesn't say anything about threads, but we can
exterpolate most things rather intuitively -- the main unanswered
question concerns the initialization of local static variables (or even
global statics, if a constructor of a global static starts a thread).
I just can write vector<int> and don't need to know anything about the
memory system. The Boost library has cross platform thread support:

Except that it doesn't work for the most important platform: mine:).

At least if I understand the documentation correctly, it also can't be
used directly for what is one of the more common locking idioms in my
code: the lock is acquired in a function and is returned as part of the
return value. (Typically in a sort of a smart pointer -- I acquire
access to the object and a lock for it from a single function, and
automatically free the lock when the access goes out of scope. The
entire thing works a lot like auto_ptr, with the addition that which
ever object holds the valid pointer also holds the lock.)
 
D

David Abrahams

No! I don't think I am qualified, but that doesn't mean I cannot have
a opinion about thread.

You're perfectly qualfied to have an opinion about threads. You're
not qualified to make pronouncements about what the committee thinks
is important.

For all these reasons, C++ standard
committee shall consider next standard shall support thread.

Sorry, the committee doesn't work that way. Things don't get
considered just because they're important. It's a volunteer
organization, and topics are only considered when there are people
with the energy and expertise to lead the way. If nobody who can do
that for threads shows up, nothing's going to happen.
 
D

David Abrahams

David Abrahams said:
(e-mail address removed) (David Eng) writes:
Please. Did you submit a proposal for a standard threads library?
Did anyone? [hint: the answer is no]

I was under the impression that the Boost threading library was being
discussed. Internally, of course, and only for inclusion in the next
version of the standard.

Someone may be discussing it, but if so only in the hallways between
sessions. And we don't have a proposal. Without a proposal, hallway
discussion is not very meaningful.
 
F

Francis Glassborow

David Eng said:
As I posted in CORBA group, I believe the future of C++ depends on
CORBA (the same is true that the future of CORBA depends on the future
of C++). Applications are built today are distributed applications
instead of stand alone applications.

There is a common trap that assumes that an individuals view of
something is the same as everyone else's. There are many things done
with C++ that have nothing to do with distributed systems/processes.
Indeed most of the applications I use actually have to be protected from
interference from elsewhere, they are essentially single system, local
applications. For example, when editing digital video I have absolutely
no need for any kind of distributed process and will probably disconnect
from the outside world so as to ensure that nothing interrupts the flow
of data from, for example, camera to hard drive.

In the same way, if CORBA was mainly concerned with C++ it would have no
future. Its strength is exactly that it is multi-platform,
multi-language. It would be a mistake for CORBA to tie itself to C++.

Now, unless some positive suggestions surface I do not intend to further
participate in this dialogue which seems to consist of a good number of
assertions and basically 'X ought to do something about this.' I have
long been a practitioner of the dictum 'Put up, or shut up.' I.e. if you
(generic usage) are not willing to act stop telling other people what
they should do.'
 
F

Frank Buss

Not completely. What happens if some of the generated code uses
static variables. An obvious candidate would be exception processing,
and at least one compiler I have used does fail if two threads throw
an exception at the same time.

You are right, the standard must say something about threads to ensure a
compiler, which works with threads, but the language needs not to be
changed, only some definitions for thread safety needs to be added, I
think.

This is not easy, because your problem with static variables and the like
is a general problem of imperative programming languages. The best
solution would be to start threads without manual programming it, which
is possible with referential transparency, because every part of an
expression can be evaluated without side effects:

http://c2.com/cgi/wiki?ReferentialTransparency

But would be nice to have explicit thread support for C++, because
writing imperative programs is easier, at least for me.
At least if I understand the documentation correctly, it also can't be
used directly for what is one of the more common locking idioms in my
code: the lock is acquired in a function and is returned as part of
the return value. (Typically in a sort of a smart pointer -- I
acquire access to the object and a lock for it from a single function,
and automatically free the lock when the access goes out of scope.
The entire thing works a lot like auto_ptr, with the addition that
which ever object holds the valid pointer also holds the lock.)

Looks like a mutex is what you are searching for, perhaps wrapped in a
small class with overloaded operator= etc., something like a smart
pointer which wraps a mutex.
 
K

kanze

(e-mail address removed) wrote:
[...]
At least if I understand the documentation correctly, it also can't
be used directly for what is one of the more common locking idioms
in my code: the lock is acquired in a function and is returned as
part of the return value. (Typically in a sort of a smart pointer
-- I acquire access to the object and a lock for it from a single
function, and automatically free the lock when the access goes out
of scope. The entire thing works a lot like auto_ptr, with the
addition that which ever object holds the valid pointer also holds
the lock.)
Looks like a mutex is what you are searching for, perhaps wrapped in a
small class with overloaded operator= etc., something like a smart
pointer which wraps a mutex.

I know what I am looking for; I've even written it for Posix compatible
platforms:). You cut the sentence I was responding to: a
recommendation to use Boost's threading package. Boost's threading
package requires the lock on a mutex to have lexical scope; there are a
lot of times when my locks don't -- the respect transfer of ownership
rules much like those of auto_ptr. And I could imagine that there are
cases where one might want shared ownership as well; after all, most of
the time, you lock to protect access to memory, so it isn't surprising
to find the same idioms for possession of locks as for possession of
memory.
 
D

David Abrahams

(e-mail address removed) wrote:
[...]
At least if I understand the documentation correctly, it also can't
be used directly for what is one of the more common locking idioms
in my code: the lock is acquired in a function and is returned as
part of the return value. (Typically in a sort of a smart pointer
-- I acquire access to the object and a lock for it from a single
function, and automatically free the lock when the access goes out
of scope. The entire thing works a lot like auto_ptr, with the
addition that which ever object holds the valid pointer also holds
the lock.)
Looks like a mutex is what you are searching for, perhaps wrapped in a
small class with overloaded operator= etc., something like a smart
pointer which wraps a mutex.

I know what I am looking for; I've even written it for Posix compatible
platforms:). You cut the sentence I was responding to: a
recommendation to use Boost's threading package. Boost's threading
package requires the lock on a mutex to have lexical scope; there are a
lot of times when my locks don't -- the respect transfer of ownership
rules much like those of auto_ptr.

That's why we didn't prohibit dynamic allocation of locks ;-)
Yes, a moveable but non-copyable lock would be better.
 
K

kanze

David Abrahams said:
(e-mail address removed) writes:
(e-mail address removed) wrote:
[...]
At least if I understand the documentation correctly, it also
can't be used directly for what is one of the more common
locking idioms in my code: the lock is acquired in a function
and is returned as part of the return value. (Typically in a
sort of a smart pointer -- I acquire access to the object and a
lock for it from a single function, and automatically free the
lock when the access goes out of scope. The entire thing works
a lot like auto_ptr, with the addition that which ever object
holds the valid pointer also holds the lock.)
Looks like a mutex is what you are searching for, perhaps wrapped
in a small class with overloaded operator= etc., something like a
smart pointer which wraps a mutex.
I know what I am looking for; I've even written it for Posix
compatible platforms:). You cut the sentence I was responding to:
a recommendation to use Boost's threading package. Boost's
threading package requires the lock on a mutex to have lexical
scope; there are a lot of times when my locks don't -- the respect
transfer of ownership rules much like those of auto_ptr.
That's why we didn't prohibit dynamic allocation of locks ;-)

Yes. std::auto_ptr< boost::lock > would do the trick:). However:

I originally started thinking about the issue during an email discussion
with Scott Meyers over the double checked locking idiom for a
singleton. The fact is that there is no correct implementation which
doesn't either lock on every call to Singleton::instance, or use
assembler or some other very special code to implement memory barriers.
But it occured to me that very often, using the singleton, once you
acquired the reference to it, would also require a lock, and that in
such cases, if you used the same lock when accessing the singleton AND
in Singleton::instance(), you don't pay any more for locking than if
Singleton::instance() wasn't locked -- all you've done is move the
acquisition of the lock necessary to use the singleton forward.

And while using
std::auto_ptr< boost::lock >( new boost::lock( someMutex ) )
would certainly fulfil the desired semantics, I suspect that most
implementations of operator new will also acquire a lock, which defeats
the whole purpose of the exercise.

Now, I basically think that the "correct" solution is to just lock in
Singleton::instance(), and then lock when you access the object, using
two separate lock/unlock sequences, at least until the profiler says
otherwise. And that when the profiler says otherwise, the simplest
solution is just to drop the locks in Singleton::instance(), and ensure
that Singleton::instance() is called at least once before threading is
started. But the context of the discussion was saving a lock, and the
problem is intellectually stimulating, even if it is of no practical
interest:).

And finally, having thought about all this, it occured to me that we do
something similar in our current application. In our case, it isn't
singletons, but objects acquired from our data base -- we acquire an
object through a smart pointer, which also manages a lock on the
object. Here too, I'm not convinced that this is the right solution --
we now access several different objects in the same transaction, which
requires some special, and fairly complex, code to avoid deadlocks. But
it was a very elegant solution for the initial requirements, where the
code never accessed more than one object at a time.
Yes, a moveable but non-copyable lock would be better.

Or maybe a lock-ownership policy:). I can imagine that there are a few
cases where reference counted locks might be reasonable too.

Seriously, I'm against over complexity. The Boost solution is right
something between 90-95% of the time. All I'd ask for is access to the
underlying lock()/unlock() functions on mutex, so I can provide a custom
solution for the few remaining cases.
 
A

Alexander Terekhov

I originally started thinking about the issue during an email discussion
with Scott Meyers over the double checked locking idiom for a
singleton. The fact is that there is no correct implementation which
doesn't either lock on every call to Singleton::instance, or use
assembler or some other very special code to implement memory barriers.

Thread-specific data can be used instead of atomic said:
But it occured to me that very often, using the singleton, once you
acquired the reference to it, would also require a lock,

Not if it's immutable (or uses atomic<> internally).

regards,
alexander.
 
D

David Abrahams

Yes. std::auto_ptr< boost::lock > would do the trick:). However:

I originally started thinking about the issue during an email discussion
with Scott Meyers over the double checked locking idiom for a
singleton. The fact is that there is no correct implementation which
doesn't either lock on every call to Singleton::instance, or use
assembler or some other very special code to implement memory barriers.

You use boost::call_once and that problem goes away.
 

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

Similar Threads

Future of C++ 79
The Future of C++ ? 190
Future standard GUI library 51
C and the future of computing 0
Become a C++ programmer 5
The future of c++ 8
python's future? 5
The future of C++ 8

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top