Monday, August 27, 2018

Digest for comp.lang.c++@googlegroups.com - 9 updates in 2 topics

Juha Nieminen <nospam@thanks.invalid>: Aug 27 06:20AM

> member function should indicate that it's thread-safe to call it
> without a locking mechanism."
 
> That is not what the C++ standard library provides.
 
Where exactly are you getting this "C++ standard library" from? Not from
my post at least. Nowhere did I made any mention whatsoever, not even
indirectly, about the C++ standard library.
 
Anyway, that doesn't matter, because *according to you* the C++ standard
library *does exactly* what I was talking about. Let me quote your own
post:
 
"All that the C++ standard guarantees is that a const member function
can safely be called concurrently with another thread calling that or
another const member function on the same object, provided that no
non-const member function is called concurrently on the object."
 
This is exactly what I was referring to. If you were confused by my
use of the term "thread-safe", then replace it with whatever other word
you want. However, don't cling onto whatever meaning you want to apply
to that term as if that had been what I meant, if I'm telling you what
I meant when I used it.
 
> is wrong. In this business, labelling a function "thread-safe" means
> that users do not need to provide external synchronisation to maintain
> invariants, irrespective of what other threads are doing.
 
So you *are* nitpicking about the terminology.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 27 11:09AM +0100

On Mon, 27 Aug 2018 06:20:16 -0000 (UTC)
> > that users do not need to provide external synchronisation to maintain
> > invariants, irrespective of what other threads are doing.
 
> So you *are* nitpicking about the terminology.
 
Garbage.
 
"Even beyond that, in the era of C++11 and newer, the constness of a
member function should indicate that it's thread-safe to call it
without a locking mechanism."
 
Maybe you just expressed yourself poorly, maybe you don't understand
multi-threaded code. Since you are resolutely arguing the unarguable,
who knows.
 
Mistakes happen and this one is not the end of the world (unless you
are actually writing multi-threaded code for clients "without a locking
mechanism" for const methods operating on objects mutable by other
threads). Move on. And when you are in a hole, stop digging.
Juha Nieminen <nospam@thanks.invalid>: Aug 27 04:42PM

> are actually writing multi-threaded code for clients "without a locking
> mechanism" for const methods operating on objects mutable by other
> threads). Move on. And when you are in a hole, stop digging.
 
So even after I clearly explain what I meant, you still choose to act
like an a-hole.
 
I explained in this thread, again and again, multiple times, that what
I mean is that "a const method should be implemented so that it can be
safely called from multiple threads without the need of a locking
mechanism". It's not even my idea.
 
Now you cling onto that term "thread-safe", apply your particular
meaning to it, rather than asking me what I meant, and declare yourself
victorious, and proceed to mock me.
 
You also conjured the C++ standard library from somewhere, even though
nowhere did I mention anything about it, and then you just ignore that.
Hilariously, you proceeded to explain that the C++ standard library
behaves *EXACTLY* like I described const member functions to be
supposed to behave. Yet, still, I am the one who is somehow in the wrong
here. Because of that one term "thread-safe" in one post, which you still
keep clinging onto.
woodbrian77@gmail.com: Aug 27 10:00AM -0700

On Monday, August 27, 2018 at 11:43:06 AM UTC-5, Juha Nieminen wrote:
> supposed to behave. Yet, still, I am the one who is somehow in the wrong
> here. Because of that one term "thread-safe" in one post, which you still
> keep clinging onto.
 
 
There's no shortage of "intelligent, but" people here like Chris.
The best thing I can say about them is they are intelligent. I've
called them "little vultures" before -- they wait for someone to
trip and then try to pounce on them. Little vultures == gnats.
 
 
Brian
Ebenezer Enterprises - "If a good man falls seven times, he gets back up.
But when trouble strikes the wicked, that's the end of them." Proverbs 24:16
 
http://webEbenezer.net
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 27 08:25PM +0100

On Mon, 27 Aug 2018 16:42:52 -0000 (UTC)
> I mean is that "a const method should be implemented so that it can be
> safely called from multiple threads without the need of a locking
> mechanism". It's not even my idea.
 
I would not agree with that point either. Const methods should, in my
opinion, be implemented so that they can safely be called from multiple
threads without the need for a locking mechanism provided that the
object concerned cannot also be concurrently mutated by a non-const
method. If it can be concurrently mutated the user needs an external
locking mechanism. It also happens to the be approach adopted by most
code I have seen, including the standard library.
 
> supposed to behave. Yet, still, I am the one who is somehow in the wrong
> here. Because of that one term "thread-safe" in one post, which you still
> keep clinging onto.
 
I am not trying to mock you. I was trying to point out, apparently
unsuccessfully, that if you think that invoking a const method is going
to be thread-safe by virtue of it being const, you will be writing
thread-unsafe code. I think you are so self-defensive that you have
become confused.
 
As to the meaning of "thread-safe", (i) it is well established in the
industry, and (ii) words cannot just mean whatever you want them to
mean.
 
Humpty Dumpty: "... There's glory for you!"
 
"I don't know what you mean by 'glory'," Alice said.
 
Humpty Dumpty smiled contemptuously. "Of course you don't – till I
tell you. I meant 'there's a nice knock-down argument for you!'"
 
"But 'glory' doesn't mean 'a nice knock-down argument'," Alice
objected.
 
"When I use a word," Humpty Dumpty said, in a rather scornful tone,
"it means just what I choose it to mean – neither more nor less."
 
"The question is," said Alice, "whether you can make words mean so
many different things."
 
"The question is," said Humpty Dumpty, "which is to be master - that's
all."
 
I am with Alice, not Humpty Dumpty.
Vir Campestris <vir.campestris@invalid.invalid>: Aug 27 10:53PM +0100

On 27/08/2018 17:42, Juha Nieminen wrote:
> I mean is that "a const method should be implemented so that it can be
> safely called from multiple threads without the need of a locking
> mechanism". It's not even my idea.
 
I've read all through this thread.
 
Can I make a general appeal here to everyone to not drop to insults? It
doesn't help.
 
That aside, the view I've always taken for a const method is "it won't
alter the visible state of the object".
 
I can imagine a method that makes a summary of the state of the object.
Suppose, for example, the collection can be boiled down to a string. The
to_str() method would collate whatever data was needed to represent the
object. That might involve significant calculations, and might be enough
that it's worth caching the string internally.
 
If calling the method from two threads simultaneously is permitted then
the method will have to take a lock on the cache before operating.
 
If the method will only ever be run in a single-threaded context then
there is no need for the lock, and it is unnecessary overhead.
 
It may be that in your application the use of threads is so widespread
that it is worth having a coding standard that states that all const
methods must be able to run concurrently with all other const methods,
and that this makes the maintenance of your codebase easier. In fact, it
probably does (and the codebase I am working on now might benefit from
such a standard!)
 
BUT
 
It's not something that is needed everywhere. Specifically it is not
needed for single threaded applications, and will only add complexity.
Which means potential bugs.
 
So I don't support your idea that _all_ const methods should be thread safe.
 
Andy
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 27 11:19PM +0100

On Mon, 27 Aug 2018 22:53:17 +0100
> and that this makes the maintenance of your codebase easier. In fact, it
> probably does (and the codebase I am working on now might benefit from
> such a standard!)
 
I do aim for that standard in my code. I don't think it causes much
overhead. Generally it just requires locking of any member data marked
'mutable' and, so far as relevant, any static data, and synchronization
of any i/o done by const methods. That is normally about it.
 
The C++ standard library adopts this approach.
 
> .. I don't support your idea that _all_ const methods should be thread safe.
 
I am strongly against that. That would cause unacceptable overhead in
my view. It would require locking of all member or static data read by
the const methods which might be mutated by non-const methods. To make
all const methods thread-safe you practically have to make all non-const
methods thread safe as well.
 
I think that it is better to leave such cases to external
synchronization by the user. That is also the approach adopted by the
standard library, except where otherwise stated. (Obviously things like
mutexes have to be thread-safe.)
 
Chris
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Aug 27 03:24PM -0700

On 8/27/2018 9:42 AM, Juha Nieminen wrote:
> I mean is that "a const method should be implemented so that it can be
> safely called from multiple threads without the need of a locking
> mechanism". It's not even my idea.
 
What about const functions that are only called from a single thread?
Say the const function is on a per-thread data structure. Why would the
function need any synchronization if it only operates on data that is
totally owned by the only thread that will ever call it?
________________________
class per_thread
{
int foo;
 
public:
per_thread(int foo_) : foo(foo_) {}
 
public:
int get() const
{
return foo + 21;
}
};
________________________
 
There is no need to make per_thread::foo an atomic type.
 
 
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Aug 27 02:45PM +0100

Hi.
 
Here I present "intrusive_sort" which works like std::sort except that you
pass it a custom "swapper" functor that is used to exchange elements as
required by the sort algorithm. The swapper is passed the iterators of
the two elements that require exchanging.
 
Example usage:
 
neolib::intrusive_sort(component_data().begin(), component_data().end(),
[this](auto lhs, auto rhs)
{
std::swap(*lhs, *rhs);
auto lhsIndex = lhs - component_data().begin();
auto rhsIndex = rhs - component_data().begin();
std::swap(index()[lhsIndex], index()[rhsIndex]);
std::swap(reverse_index()[index()[lhsIndex]],
reverse_index()[index()[rhsIndex]]);
},
[](const rigid_body& lhs, const rigid_body& rhs)
{
return lhs.mass > rhs.mass;
});
 
As you can see intrusive_sort allows us to sort multiple containers in
parallel in a single operation. An alternative approach using a zip
iterator and std::sort wouldn't work in this case as 'reverse_index()' is
a sparse reverse-lookup array.
 
intrusive_sort has the same complexity guarantees as std::sort.
 
https://github.com/i42output/neolib/blob/master/include/neolib/intrusive_sort.hpp
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: