Topic: std::lock and std::lock_guard for
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Tue, 12 Jul 2016 15:34:28 -0400
Raw View
--Apple-Mail=_C393CB53-614F-4929-9F35-8246084FC829
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
On Jul 12, 2016, at 3:09 PM, 'Bernd' via ISO C++ Standard - Future Proposal=
s <std-proposals@isocpp.org> wrote:
>=20
> In discussions on Andrei's NDC talk about folly/Synchronized [1] the ques=
tion came up why his deadlock prevention [2] did not just use std::lock(). =
It was pointed out that this is due to using SharedLockable::lock_shared(),=
making std::lock() the wrong thing. There is the workaround of
>=20
> std::shared_mutex a, b;
> std::shared_lock<> lock_a (a, std::defer_lock);
> std::shared_lock<> lock_b (b, std::defer_lock);
> std::lock (lock_a, lock_b);
>=20
> using the shared_lock adapter exposing SharedLockable as Lockable. Note t=
hat the inverse order of std::lock and std::shared_lock (using std::adopt_l=
ock) requires manual deadlock prevention. Note that the locks also have to =
be non-const which is undesirable.
>=20
> I propose adding std::lock_shared (SharedLockable&...) to allow said inve=
rse order, for consistency:
>=20
> std::shared_mutex a, b;
> std::lock_shared (a, b);
> std::shared_lock<> const lock_a (a, std::adopt_lock);
> std::shared_lock<> const lock_b (b, std::adopt_lock);
>=20
> On the same note, C++17 added std::lock_guard<Lockable...>, which has no =
SharedLockable variant either, which would make the above code even easier:
>=20
> std::shared_lock_guard<> const lock_both (a, b);
>=20
> The biggest issue I can see with it is that combining locking a Lockable =
and a SharedLockable at once, which still requires the defer_lock approach =
or manual deadlock prevention. It feels like this was an oversight when add=
ing SharedLockable and an easy addition of basically "do as std::lock, but =
use _shared methods=E2=80=9D.
I can assure you it wasn=E2=80=99t an oversight. And your first =E2=80=9Cw=
orkaround=E2=80=9D is the intended use.
We don=E2=80=99t need or want a =E2=80=9Ckitchen sink=E2=80=9D API where th=
ere are 3 three different ways to do everything. We already have that with=
std::string, and we don=E2=80=99t need to repeat that design mistake.
The =E2=80=9Cmixed case=E2=80=9D you speak of at the end is actually a very=
prominent use case:
class A
{
using ReadLock std::shared_lock<std::shared_mutex>;
using WriteLock std::unique_lock<std::shared_mutex>;
mutable std::shared_mutex mut_;
public:
// ...
A& operator=3D(const A& a)
{
if (this !=3D &a)
{
WriteLock this_lock(mut_, std::defer_lock);
ReadLock that_lock(a.mut_, std::defer_lock);
std::lock(this_lock, that_lock);
// mut_ is now unique-locked and a.mut_ is now share-locked
// ... now safe to assign data ...
} // mut_ and a.mut_ now unlocked, even if there was an excep=
tion
return *this;
}
// ...
};
Howard
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/2DCF8C2C-C662-49EE-B7E5-3FA11B47AB58%40gmail.com=
..
--Apple-Mail=_C393CB53-614F-4929-9F35-8246084FC829
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCAAGBQJXhUZKAAoJEGbcHCxKqhWCX2YP/0mqL7P/U1Ms2rqDm8Mwkvw+
vWsIHav10+U27M63jz9Az4xb3VBAKlmMGY/BFWozJookgVxH8LbZyWHoBRyOEsS6
C5w+QRJxNo1BF0UcbRXwHIG5pscSovPwlc1Y74mDCom9U+JA7gzJF9JF5keQCmwG
lDUfcNRB+5huygMMk/8WSWNgdgPCCDEJu9NtMDer1fWT5M1bo3qGal/vPNmXySM5
B5LmD4GZBWpPpn2Q/YxYbIRtGQ6vUCDu+NbF6ou59pT6tkczk9GZNo8v+JmMWqPj
7ZdG1Kul7LTZgaNb0oV/p9l31lkGF5Vsz/pHc+KXLIM1L7e70UlnPxbUMPOoDDxV
+gOnnWEsNFzSgztvKVSR2JAve9ZjnkVSP3vebO4Oaf/igYJ4SxTT0wMMZXFYZaSu
RqarcSBGXi2/zpxLp5q8+NL1g0KWW6Wgf5uBEDrBOEd9WGuwUTB5GXmnokc7Q3vf
ERPb47NrSRJZZjSvtP4/IzRrGz2DaaP2pMVwfuryzrr/FzTjG7G/C++TRcUYdcU6
ksib1Wm2omzPttSvT4k7ln7JhFwco1E/aS6z7GQoiPKbdDMljuHeIF5+4y7+OH9u
g97zAYcOcGG/rmgQnSxI+2d/NNkwe/oSaMiVpa8eExV7/3+uXifXot9BjGaPiyxu
6sbRNTUQxZvCv7QEfzR4
=Rwpi
-----END PGP SIGNATURE-----
--Apple-Mail=_C393CB53-614F-4929-9F35-8246084FC829--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 12 Jul 2016 22:55:48 -0700 (PDT)
Raw View
------=_Part_566_1377096605.1468389348938
Content-Type: multipart/alternative;
boundary="----=_Part_567_727435535.1468389348938"
------=_Part_567_727435535.1468389348938
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, July 12, 2016 at 12:34:38 PM UTC-7, Howard Hinnant wrote:
>
> On Jul 12, 2016, at 3:09 PM, 'Bernd' via ISO C++ Standard - Future=20
> Proposals <std-pr...@isocpp.org <javascript:>> wrote:=20
> >=20
> > In discussions on Andrei's NDC talk about folly/Synchronized [1] the=20
> question came up why his deadlock prevention [2] did not just use=20
> std::lock(). It was pointed out that this is due to using=20
> SharedLockable::lock_shared(), making std::lock() the wrong thing. [...]
> > I propose adding std::lock_shared (SharedLockable&...)
>
[...]=20
> > On the same note, C++17 added std::lock_guard<Lockable...>, which has n=
o=20
> SharedLockable variant either [...]
>
> I can assure you it wasn=E2=80=99t an oversight. And your first =E2=80=
=9Cworkaround=E2=80=9D is=20
> the intended use.=20
>
> We don=E2=80=99t need or want a =E2=80=9Ckitchen sink=E2=80=9D API where =
there are 3 three=20
> different ways to do everything. We already have that with std::string,=
=20
> and we don=E2=80=99t need to repeat that design mistake.=20
>
As someone who wasn't involved at all in the design process for=20
lock/shared_lock/lock_guard, let me add another reason NOT to add more lock=
=20
variants than we already have: massive confusion for newbies.
When I first learned about std::mutex and std::lock_guard, I thought it was=
=20
the neatest thing ever.
Then I learned about std::unique_lock, which was even neater =E2=80=94 it w=
as like=20
lock_guard, but you could actually pass it around from place to place. Mind=
=20
you, you couldn't *copy* it =E2=80=94 it was a move-only type =E2=80=94 thi=
s was obviously=20
why they called it *unique*_lock, just like C++11's other move-only type,=
=20
*unique*_ptr.
Then came shared_mutex. Which kind of makes sense as a name... kind of. I=
=20
mean, anyone who's taken Operating Systems in university knows that what it=
=20
really is is a reader-writer lock=20
<https://en.wikipedia.org/wiki/Readers=E2=80=93writer_lock>, a.k.a. r=20
<https://doc.rust-lang.org/std/sync/struct.RwLock.html>w=20
<https://www.npmjs.com/package/rwlock>lo=20
<http://linux.die.net/man/3/pthread_rwlock_init>c=20
<http://www.freebsd.org/cgi/man.cgi?query=3Drwlock&sektion=3D9>k=20
<http://docs.libuv.org/en/v1.x/threading.html#read-write-locks>, but okay,=
=20
the Committee hates acronyms or something, so yeah, it does behave kind of=
=20
like a mutex that you can "share". And so it has a method lock_shared().=
=20
Makes sense if you think about it.
And then... wait a minute. Was my intuition about unique_lock wrong? Did it=
=20
actually get its name not because it's move-only, but because it takes an=
=20
*exclusive* lock on the mutex it controls? (Seeing the Committee fumble=20
the noun "rwlock" leads to the horrible thought that they might equally=20
have fumbled the adjective "exclusive".) So then what's a *shared*_lock?=
=20
....which showed up in C++14, as a move-only type! This way lies madness.=20
Best to just sweep it under the bed and try to forget about it.
I welcome anything the Committee can do at this point to limit the=20
confusion and preserve the general principle of "*unique_* things are=20
move-only, *shared_* things are copyable, and things pretty much do what=20
they say on the tin (except for shared_mutex which is really rwlock in=20
disguise, oops)" =E2=80=94 which means I would attempt to oppose the additi=
on of=20
any new *shared_* stuff to the library unless it really clearly did what it=
=20
appeared to say on the tin.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/cd6a8704-4358-4698-85ba-05dd65396190%40isocpp.or=
g.
------=_Part_567_727435535.1468389348938
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 12, 2016 at 12:34:38 PM UTC-7, Howard Hin=
nant wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Jul 12, 2016, at=
3:09 PM, 'Bernd' via ISO C++ Standard - Future Proposals <<a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"oUs14168CgAJ"=
rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return t=
rue;" onclick=3D"this.href=3D'javascript:';return true;">std-pr...@=
isocpp.org</a>> wrote:
<br>>=20
<br>> In discussions on Andrei's NDC talk about folly/Synchronized [=
1] the question came up why his deadlock prevention [2] did not just use st=
d::lock(). It was pointed out that this is due to using SharedLockable::loc=
k_shared(), making std::lock() the wrong thing. [...]<br>> I propose add=
ing std::lock_shared (SharedLockable&...)<br></blockquote><div>[...]=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">> On the same note=
, C++17 added std::lock_guard<Lockable...>, which has no SharedLockab=
le variant either [...]<br>
<br>I can assure you it wasn=E2=80=99t an oversight. =C2=A0And your first =
=E2=80=9Cworkaround=E2=80=9D is the intended use.
<br>
<br>We don=E2=80=99t need or want a =E2=80=9Ckitchen sink=E2=80=9D API wher=
e there are 3 three different ways to do everything. =C2=A0We already have =
that with std::string, and we don=E2=80=99t need to repeat that design mist=
ake.
<br></blockquote><div><br></div><div>As someone who wasn't involved at =
all in the design process for lock/shared_lock/lock_guard, let me add anoth=
er reason NOT to add more lock variants than we already have: massive confu=
sion for newbies.</div><div><br></div><div>When I first learned about std::=
mutex and std::lock_guard, I thought it was the neatest thing ever.</div><d=
iv>Then I learned about std::unique_lock, which was even neater =E2=80=94 i=
t was like lock_guard, but you could actually pass it around from place to =
place. Mind you, you couldn't <i><b>copy</b></i> it =E2=80=94 it was a =
move-only type =E2=80=94 this was obviously why they called it <i><b>unique=
</b></i>_lock, just like C++11's other move-only type, <i><b>unique</b>=
</i>_ptr.</div><div><br></div><div>Then came shared_mutex. Which kind of ma=
kes sense as a name... kind of. I mean, anyone who's taken Operating Sy=
stems in university knows that what it really is is a <a href=3D"https://en=
..wikipedia.org/wiki/Readers=E2=80=93writer_lock">reader-writer lock</a>, a.=
k.a. <a href=3D"https://doc.rust-lang.org/std/sync/struct.RwLock.html">r</a=
><a href=3D"https://www.npmjs.com/package/rwlock">w</a><a href=3D"http://li=
nux.die.net/man/3/pthread_rwlock_init">lo</a><a href=3D"http://www.freebsd.=
org/cgi/man.cgi?query=3Drwlock&sektion=3D9">c</a><a href=3D"http://docs=
..libuv.org/en/v1.x/threading.html#read-write-locks">k</a>, but okay, the Co=
mmittee hates acronyms or something, so yeah, it does behave kind of like a=
mutex that you can "share". =C2=A0And so it has a method lock_sh=
ared(). =C2=A0Makes sense if you think about it.</div><div><br></div><div>A=
nd then... wait a minute. Was my intuition about unique_lock wrong? Did it =
actually get its name not because it's move-only, but because it takes =
an <i><b>exclusive</b></i> lock on the mutex it controls? =C2=A0(Seeing the=
Committee fumble the noun "rwlock" leads to the horrible thought=
that they might equally have fumbled=C2=A0the adjective "exclusive&qu=
ot;.) =C2=A0So then what's a <i>shared</i>_lock? ...which showed up in =
C++14, as a move-only type! This way lies madness. Best to just sweep it un=
der the bed and try to forget about it.</div><div><br></div><div>I welcome =
anything the Committee can do at this point to limit the confusion and pres=
erve the general principle of "<i>unique_</i>=C2=A0things are move-onl=
y, <i>shared_</i>=C2=A0things are copyable, and things pretty much do what =
they say on the tin (except for shared_mutex which is really rwlock in disg=
uise, oops)" =E2=80=94 which means I would attempt to oppose the addit=
ion of any new <i>shared_</i> stuff to the library unless it really clearly=
did what it appeared to say on the tin.</div><div><br></div><div>=E2=80=93=
Arthur</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cd6a8704-4358-4698-85ba-05dd65396190%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cd6a8704-4358-4698-85ba-05dd65396190=
%40isocpp.org</a>.<br />
------=_Part_567_727435535.1468389348938--
------=_Part_566_1377096605.1468389348938--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Wed, 13 Jul 2016 11:24:18 +0300
Raw View
On 07/13/16 08:55, Arthur O'Dwyer wrote:
>
> As someone who wasn't involved at all in the design process for
> lock/shared_lock/lock_guard, let me add another reason NOT to add more
> lock variants than we already have: massive confusion for newbies.
>
> When I first learned about std::mutex and std::lock_guard, I thought it
> was the neatest thing ever.
> Then I learned about std::unique_lock, which was even neater =E2=80=94 it=
was
> like lock_guard, but you could actually pass it around from place to
> place. Mind you, you couldn't /*copy*/ it =E2=80=94 it was a move-only ty=
pe =E2=80=94
> this was obviously why they called it /*unique*/_lock, just like C++11's
> other move-only type, /*unique*/_ptr.
>
> Then came shared_mutex. Which kind of makes sense as a name... kind of.
> I mean, anyone who's taken Operating Systems in university knows that
> what it really is is a reader-writer lock
> <https://en.wikipedia.org/wiki/Readers=E2=80=93writer_lock>, a.k.a. r
> <https://doc.rust-lang.org/std/sync/struct.RwLock.html>w
> <https://www.npmjs.com/package/rwlock>lo
> <http://linux.die.net/man/3/pthread_rwlock_init>c
> <http://www.freebsd.org/cgi/man.cgi?query=3Drwlock&sektion=3D9>k
> <http://docs.libuv.org/en/v1.x/threading.html#read-write-locks>, but
> okay, the Committee hates acronyms or something, so yeah, it does behave
> kind of like a mutex that you can "share". And so it has a method
> lock_shared(). Makes sense if you think about it.
>
> And then... wait a minute. Was my intuition about unique_lock wrong? Did
> it actually get its name not because it's move-only, but because it
> takes an /*exclusive*/ lock on the mutex it controls?
Yes. You can also say the lock offers a unique access to the resource=20
protected by the mutex.
> (Seeing the
> Committee fumble the noun "rwlock" leads to the horrible thought that
> they might equally have fumbled the adjective "exclusive".) So then
> what's a /shared/_lock? ...which showed up in C++14, as a move-only
> type! This way lies madness. Best to just sweep it under the bed and try
> to forget about it.
I don't see the problem. The shared lock offers a shared access to the=20
resource, so the name is fitting. The lock could potentially be made=20
copyable but this would require unnecessary overhead because normally=20
you don't want to copy locks, only move.
> I welcome anything the Committee can do at this point to limit the
> confusion and preserve the general principle of "/unique_/ things are
> move-only, /shared_/ things are copyable, and things pretty much do what
> they say on the tin (except for shared_mutex which is really rwlock in
> disguise, oops)" =E2=80=94 which means I would attempt to oppose the addi=
tion of
> any new /shared_/ stuff to the library unless it really clearly did what
> it appeared to say on the tin.
The tail doesn't wag the dog. Objects representing unique resources are=20
movable-only because when you allow copying there appears two objects=20
owning the same resource. Objects representing shared resources don't=20
have that restriction but they still can be movable-only for other=20
reasons. In either case, the types are not named unique or shared=20
because they are movable-only or not - copyability and movability are=20
the consequence and not the cause.
As for the shared_lock_guard, I do think it is needed, even if not the=20
variadic version. Most of the time I use lock_guard instead of=20
unique_lock because I don't need neither movability nor elaborate=20
constructors or lock methods - I just want to have a locked scope and=20
nothing more. The most frequent use of unique_lock for me is with a=20
condition variable. I barely ever use std::lock and frankly if you need=20
to have multiple resources locked then chances are high that you have a=20
design problem. I believe, with shared locks the situation will be even=20
more emphasized because you can't use shared locks with condition variables=
..
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5785FAB2.2000203%40gmail.com.
.
Author: =?UTF-8?Q?=27Bernd_L=C3=B6rwald=27_via_ISO_C=2B=2B_Standard_=2D_Future_Proposal?=
Date: Wed, 13 Jul 2016 12:17:27 +0200
Raw View
--94eb2c123794687cb8053781b2c7
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
I understand the goal of not cluttering the API with a thousand ways, as
well as not trying to confuse users. The unique_lock vs lock_guard naming
issue has infact also confused me the first few times I used it, and I keep
checking back if I'm actually using the right one from time to time.
I want to highlight Andrey's point on the shared_lock_guard part: Most uses
of locks are not unlocking, but using pure RAII style locking, and
expressing this intent when locking multiple mutexes is currently not
possible:
* Due to defer_lock the shared_lock has to be non-const, only the
lock_guard referencing the shared_locks can be const,
* if using std::lock like in Howard's example means nothing is const.
* Having const shared_locks via adopt_lock requires external deadlock
protection which the library can probably do better.
Note that boost already provides a shared_lock_guard (Mutex&) as extension
[1], but like the STL does not provide a std::lock equivalent. I see the
that mixed-locks are common, so I understand that decision. Best I can come
up with for that is on overload
std::lock (LockableOrSharedLockable1&, Policy1, =E2=80=A6);
to be used as
std::lock (other.mutex_, std::lock_shared, mutex_, std::lock_exclusive)=
;
which is somewhat ugly but would do the job. (And yes, I know this doesn't
make the API thinner.)
[1]
http://www.boost.org/doc/libs/1_61_0/doc/html/thread/synchronization.html#t=
hread.synchronization.other_locks.shared_lock_guard
2016-07-13 10:24 GMT+02:00 Andrey Semashev <andrey.semashev@gmail.com>:
> On 07/13/16 08:55, Arthur O'Dwyer wrote:
>
>>
>> As someone who wasn't involved at all in the design process for
>> lock/shared_lock/lock_guard, let me add another reason NOT to add more
>> lock variants than we already have: massive confusion for newbies.
>>
>> When I first learned about std::mutex and std::lock_guard, I thought it
>> was the neatest thing ever.
>> Then I learned about std::unique_lock, which was even neater =E2=80=94 i=
t was
>> like lock_guard, but you could actually pass it around from place to
>> place. Mind you, you couldn't /*copy*/ it =E2=80=94 it was a move-only t=
ype =E2=80=94
>> this was obviously why they called it /*unique*/_lock, just like C++11's
>> other move-only type, /*unique*/_ptr.
>>
>> Then came shared_mutex. Which kind of makes sense as a name... kind of.
>> I mean, anyone who's taken Operating Systems in university knows that
>> what it really is is a reader-writer lock
>> <https://en.wikipedia.org/wiki/Readers=E2=80=93writer_lock>, a.k.a. r
>> <https://doc.rust-lang.org/std/sync/struct.RwLock.html>w
>> <https://www.npmjs.com/package/rwlock>lo
>> <http://linux.die.net/man/3/pthread_rwlock_init>c
>> <http://www.freebsd.org/cgi/man.cgi?query=3Drwlock&sektion=3D9>k
>> <http://docs.libuv.org/en/v1.x/threading.html#read-write-locks>, but
>> okay, the Committee hates acronyms or something, so yeah, it does behave
>> kind of like a mutex that you can "share". And so it has a method
>> lock_shared(). Makes sense if you think about it.
>>
>> And then... wait a minute. Was my intuition about unique_lock wrong? Did
>> it actually get its name not because it's move-only, but because it
>> takes an /*exclusive*/ lock on the mutex it controls?
>>
>
> Yes. You can also say the lock offers a unique access to the resource
> protected by the mutex.
>
> (Seeing the
>> Committee fumble the noun "rwlock" leads to the horrible thought that
>> they might equally have fumbled the adjective "exclusive".) So then
>> what's a /shared/_lock? ...which showed up in C++14, as a move-only
>> type! This way lies madness. Best to just sweep it under the bed and try
>> to forget about it.
>>
>
> I don't see the problem. The shared lock offers a shared access to the
> resource, so the name is fitting. The lock could potentially be made
> copyable but this would require unnecessary overhead because normally you
> don't want to copy locks, only move.
>
> I welcome anything the Committee can do at this point to limit the
>> confusion and preserve the general principle of "/unique_/ things are
>> move-only, /shared_/ things are copyable, and things pretty much do what
>> they say on the tin (except for shared_mutex which is really rwlock in
>> disguise, oops)" =E2=80=94 which means I would attempt to oppose the add=
ition of
>> any new /shared_/ stuff to the library unless it really clearly did what
>> it appeared to say on the tin.
>>
>
> The tail doesn't wag the dog. Objects representing unique resources are
> movable-only because when you allow copying there appears two objects
> owning the same resource. Objects representing shared resources don't hav=
e
> that restriction but they still can be movable-only for other reasons. In
> either case, the types are not named unique or shared because they are
> movable-only or not - copyability and movability are the consequence and
> not the cause.
>
> As for the shared_lock_guard, I do think it is needed, even if not the
> variadic version. Most of the time I use lock_guard instead of unique_loc=
k
> because I don't need neither movability nor elaborate constructors or loc=
k
> methods - I just want to have a locked scope and nothing more. The most
> frequent use of unique_lock for me is with a condition variable. I barely
> ever use std::lock and frankly if you need to have multiple resources
> locked then chances are high that you have a design problem. I believe,
> with shared locks the situation will be even more emphasized because you
> can't use shared locks with condition variables.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5785FAB2.200=
0203%40gmail.com
> .
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAHoUTz9h5dXcO6SKQpe7jktene-P1K_v%2BE6JEsggQKvyp=
WdsVg%40mail.gmail.com.
--94eb2c123794687cb8053781b2c7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>I understand the goal of not cluttering the API with =
a thousand ways, as well as not trying to confuse users. The unique_lock vs=
lock_guard naming issue has infact also confused me the first few times I =
used it, and I keep checking back if I'm actually using the right one f=
rom time to time.<br><br></div><div>I want to highlight Andrey's point =
on the shared_lock_guard part: Most uses of locks are not unlocking, but us=
ing pure RAII style locking, and expressing this intent when locking multip=
le mutexes is currently not possible: <br>* Due to defer_lock the shared_lo=
ck has to be non-const, only the lock_guard referencing the shared_locks ca=
n be const, <br>* if using std::lock like in Howard's example means not=
hing is const. <br>* Having const shared_locks via adopt_lock requires exte=
rnal deadlock protection which the library can probably do better.<br><br><=
/div><div>Note that boost already provides a shared_lock_guard (Mutex&)=
as extension [1], but like the STL does not provide a std::lock equivalent=
.. I see the that mixed-locks are common, so I understand that decision. Bes=
t I can come up with for that is on overload<br><br></div><div></div><div>=
=C2=A0=C2=A0=C2=A0 std::lock (LockableOrSharedLockable1&, Policy1, =E2=
=80=A6);<br><br></div><div>to be used as <br><br></div><div>=C2=A0=C2=A0=C2=
=A0 std::lock (other.mutex_, std::lock_shared, mutex_, std::lock_exclusive)=
;<br><br></div><div>which is somewhat ugly but would do the job. (And yes, =
I know this doesn't make the API thinner.)<br></div><div><br>[1] <a hre=
f=3D"http://www.boost.org/doc/libs/1_61_0/doc/html/thread/synchronization.h=
tml#thread.synchronization.other_locks.shared_lock_guard">http://www.boost.=
org/doc/libs/1_61_0/doc/html/thread/synchronization.html#thread.synchroniza=
tion.other_locks.shared_lock_guard</a><br></div></div><div class=3D"gmail_e=
xtra"><br><div class=3D"gmail_quote">2016-07-13 10:24 GMT+02:00 Andrey Sema=
shev <span dir=3D"ltr"><<a href=3D"mailto:andrey.semashev@gmail.com" tar=
get=3D"_blank">andrey.semashev@gmail.com</a>></span>:<br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><span class=3D"">On 07/13/16 08:55, Arthur O'Dwyer wrot=
e:<br>
</span><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex"><span class=3D"">
<br>
As someone who wasn't involved at all in the design process for<br>
lock/shared_lock/lock_guard, let me add another reason NOT to add more<br>
lock variants than we already have: massive confusion for newbies.<br>
<br>
When I first learned about std::mutex and std::lock_guard, I thought it<br>
was the neatest thing ever.<br>
Then I learned about std::unique_lock, which was even neater =E2=80=94 it w=
as<br>
like lock_guard, but you could actually pass it around from place to<br></s=
pan>
place. Mind you, you couldn't /*copy*/ it =E2=80=94 it was a move-only =
type =E2=80=94<br>
this was obviously why they called it /*unique*/_lock, just like C++11'=
s<br>
other move-only type, /*unique*/_ptr.<span class=3D""><br>
<br>
Then came shared_mutex. Which kind of makes sense as a name... kind of.<br>
I mean, anyone who's taken Operating Systems in university knows that<b=
r>
what it really is is a reader-writer lock<br></span>
<<a href=3D"https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock" r=
el=3D"noreferrer" target=3D"_blank">https://en.wikipedia.org/wiki/Readers=
=E2=80=93writer_lock</a>>, a.k.a. r<br>
<<a href=3D"https://doc.rust-lang.org/std/sync/struct.RwLock.html" rel=
=3D"noreferrer" target=3D"_blank">https://doc.rust-lang.org/std/sync/struct=
..RwLock.html</a>>w<br>
<<a href=3D"https://www.npmjs.com/package/rwlock" rel=3D"noreferrer" tar=
get=3D"_blank">https://www.npmjs.com/package/rwlock</a>>lo<br>
<<a href=3D"http://linux.die.net/man/3/pthread_rwlock_init" rel=3D"noref=
errer" target=3D"_blank">http://linux.die.net/man/3/pthread_rwlock_init</a>=
>c<br>
<<a href=3D"http://www.freebsd.org/cgi/man.cgi?query=3Drwlock&sektio=
n=3D9" rel=3D"noreferrer" target=3D"_blank">http://www.freebsd.org/cgi/man.=
cgi?query=3Drwlock&sektion=3D9</a>>k<br>
<<a href=3D"http://docs.libuv.org/en/v1.x/threading.html#read-write-lock=
s" rel=3D"noreferrer" target=3D"_blank">http://docs.libuv.org/en/v1.x/threa=
ding.html#read-write-locks</a>>, but<span class=3D""><br>
okay, the Committee hates acronyms or something, so yeah, it does behave<br=
>
kind of like a mutex that you can "share".=C2=A0 And so it has a =
method<br>
lock_shared().=C2=A0 Makes sense if you think about it.<br>
<br>
And then... wait a minute. Was my intuition about unique_lock wrong? Did<br=
>
it actually get its name not because it's move-only, but because it<br>=
</span>
takes an /*exclusive*/ lock on the mutex it controls?<br>
</blockquote>
<br>
Yes. You can also say the lock offers a unique access to the resource prote=
cted by the mutex.<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><span class=3D"">
=C2=A0(Seeing the<br>
Committee fumble the noun "rwlock" leads to the horrible thought =
that<br>
they might equally have fumbled the adjective "exclusive".)=C2=A0=
So then<br></span>
what's a /shared/_lock? ...which showed up in C++14, as a move-only<spa=
n class=3D""><br>
type! This way lies madness. Best to just sweep it under the bed and try<br=
>
to forget about it.<br>
</span></blockquote>
<br>
I don't see the problem. The shared lock offers a shared access to the =
resource, so the name is fitting. The lock could potentially be made copyab=
le but this would require unnecessary overhead because normally you don'=
;t want to copy locks, only move.<br>
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><span class=3D"">
I welcome anything the Committee can do at this point to limit the<br></spa=
n>
confusion and preserve the general principle of "/unique_/ things are<=
br>
move-only, /shared_/ things are copyable, and things pretty much do what<sp=
an class=3D""><br>
they say on the tin (except for shared_mutex which is really rwlock in<br>
disguise, oops)" =E2=80=94 which means I would attempt to oppose the a=
ddition of<br></span>
any new /shared_/ stuff to the library unless it really clearly did what<sp=
an class=3D""><br>
it appeared to say on the tin.<br>
</span></blockquote>
<br>
The tail doesn't wag the dog. Objects representing unique resources are=
movable-only because when you allow copying there appears two objects owni=
ng the same resource. Objects representing shared resources don't have =
that restriction but they still can be movable-only for other reasons. In e=
ither case, the types are not named unique or shared because they are movab=
le-only or not - copyability and movability are the consequence and not the=
cause.<br>
<br>
As for the shared_lock_guard, I do think it is needed, even if not the vari=
adic version. Most of the time I use lock_guard instead of unique_lock beca=
use I don't need neither movability nor elaborate constructors or lock =
methods - I just want to have a locked scope and nothing more. The most fre=
quent use of unique_lock for me is with a condition variable. I barely ever=
use std::lock and frankly if you need to have multiple resources locked th=
en chances are high that you have a design problem. I believe, with shared =
locks the situation will be even more emphasized because you can't use =
shared locks with condition variables.<span class=3D""><br>
<br>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5785FAB2.2000203%40gmail.com" rel=3D"=
noreferrer" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgi=
d/std-proposals/5785FAB2.2000203%40gmail.com</a>.<br>
</blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAHoUTz9h5dXcO6SKQpe7jktene-P1K_v%2BE=
6JEsggQKvypWdsVg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHoUTz9h5dXcO6=
SKQpe7jktene-P1K_v%2BE6JEsggQKvypWdsVg%40mail.gmail.com</a>.<br />
--94eb2c123794687cb8053781b2c7--
.
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Wed, 13 Jul 2016 10:43:50 -0400
Raw View
--Apple-Mail=_11BD1763-8D98-4AFD-9E27-709229C0BC6D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
On Jul 13, 2016, at 4:24 AM, Andrey Semashev <andrey.semashev@gmail.com> wr=
ote:
>=20
> As for the shared_lock_guard, I do think it is needed, even if not the va=
riadic version.
Just do this:
using shared_lock_guard =3D const std::shared_lock<std::shared_mutex>;
The standard should concentrate on supplying those things that are not triv=
ial for anyone to do themselves, or is needed in virtually every program.
On Jul 13, 2016, at 6:17 AM, 'Bernd L=C3=B6rwald' via ISO C++ Standard - Fu=
ture Proposals <std-proposals@isocpp.org> wrote:
> std::lock (LockableOrSharedLockable1&, Policy1, =E2=80=A6);
>=20
> to be used as
>=20
> std::lock (other.mutex_, std::lock_shared, mutex_, std::lock_exclusiv=
e);
I await the implementation and positive field experience.
Howard
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/4CABB19C-4655-4153-8483-53E844AF1D1F%40gmail.com=
..
--Apple-Mail=_11BD1763-8D98-4AFD-9E27-709229C0BC6D
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCAAGBQJXhlOmAAoJEGbcHCxKqhWCubMP/RgrN/Ij7SOA9Ep/KZvh1lWo
9esNpsfqZqBjc7llaeye+CTGJi9r/WUa1hzsWX13DkQBEKOqw5DsqReP4unRXDg1
6eJFUStvZMb44s2ffWsQPoPc2fy3wEXrF8yDvbYMpwyO1vcCCty5Fw+IwgaP8q4w
wfpPMrBtZ37BjiTBkGR5dkqRdk4VCVv68WFA3HhWRK1m1CX3hdSAFPfJQuXCDMYy
LC717f1ExQKhoWn+6pRceMqO4ov7+WaNDBvTvNXwW943tXdMviqJaWFkgaaX78L+
/4sI64uaznh8e3FA4J6eRRQdhbSmysefDd6DFjsndQXEIhEcoeu4XKLQbAkHJDKa
GRMCZba5oTU2FyWjU9Xmv+ImGyzQ6O17wMumK4qzhWk2hf9stesNDFz0Fk/Zf2h8
HfNk31HneAnCKW7ZfjSD+70YCE/mjcd8ODvdIMOX1USSrmUziWnrTyRikLXv6wuJ
0gk39UhRlQBjeGt1wo4hIPDbmHncxnNVr6cyvMLNzi5tgKVVOSWwrbboVChJYUDA
qDEOcbTclc/5WR3SnjlF5mpsQxzAU/X7EMTsnTBF8yBOs4fL9nc1nJHMnmz+m9Ck
VzJtPWBzrdFyrQsBiH6LaADW8ZbC0cZOtTzGA8j0H5dWQGEQAkE8jNahQAvSb186
FrvPrOIIw6YdgcAZCdti
=fssk
-----END PGP SIGNATURE-----
--Apple-Mail=_11BD1763-8D98-4AFD-9E27-709229C0BC6D--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Wed, 13 Jul 2016 18:14:16 +0300
Raw View
On 07/13/16 17:43, Howard Hinnant wrote:
> On Jul 13, 2016, at 4:24 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
>>
>> As for the shared_lock_guard, I do think it is needed, even if not the variadic version.
>
> Just do this:
>
> using shared_lock_guard = const std::shared_lock<std::shared_mutex>;
That is not the same as shared_lock_guard from Boost. Similar to
lock_guard, shared_lock_guard is not movable and does not support
special constructors or methods. Consequently it does not have the
overhead of shared_lock, like lock_guard doesn't have that of unique_lock.
> The standard should concentrate on supplying those things that are not trivial for anyone to do themselves, or is needed in virtually every program.
I would argue that shared_lock_guard would be used in almost every
program involving shared_mutex.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/57865AC8.2010404%40gmail.com.
.