Tuesday, February 7, 2023

Digest for comp.lang.c++@googlegroups.com - 25 updates in 4 topics

Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 07 01:25AM -0800

Since C++11, we already have "std::timed_mutex". It will try to acquire the lock for N seconds and fail, and you can handle the failure.
 
I want to make another kind of timed mutex, called something like "std::timed_rescuable_mutex", but the difference will be that when you invoke "try_lock_for", it will wait for N seconds, and then if the mutex is still locked, it will kill the thread that locked it, and then unlock the mutex.
 
Last week I posted code here for a mutex that could be unlocked by a thread other than the one that locked it:
 
https://groups.google.com/g/comp.lang.c++/c/HtUKQlNUI50
 
Similarly, I would use an "std::atomic_flag" as a mutex that can be unlocked by any thread.
 
A well-written program should work properly 99.9% of the time. There will always be unforeseen problems like a hardware failure, or a yet-to-be-discovered bug in a third-party library, or an operating system bug, or another process is set to a high priority with high CPU usage. This is why, when I'm finished writing a program that works very well, I try to add extra robustness to it in order to try make it recover gracefully from unforeseen errors. This means I might add in code to kill a thread that has become unresponsive. This is why I'm thinking I should write a 'timed_rescuable_mutex". In my code I would then use it with "std::unique_lock::try_lock_for".
Muttley@dastardlyhq.com: Feb 07 09:40AM

On Tue, 7 Feb 2023 01:25:11 -0800 (PST)
 
> https://groups.google.com/g/comp.lang.c++/c/HtUKQlNUI50
 
>Similarly, I would use an "std::atomic_flag" as a mutex that can be unlocke=
>d by any thread.
 
Huh? If any thread can unlock a mutex then whats the point of having it in
the first place?
Bo Persson <bo@bo-persson.se>: Feb 07 10:48AM +0100

On 2023-02-07 at 10:25, Frederick Virchanza Gotham wrote:
 
> Since C++11, we already have "std::timed_mutex". It will try to acquire the lock for N seconds and fail, and you can handle the failure.
 
> I want to make another kind of timed mutex, called something like "std::timed_rescuable_mutex", but the difference will be that when you invoke "try_lock_for", it will wait for N seconds, and then if the mutex is still locked, it will kill the thread that locked it, and then unlock the mutex.
 
Killing a thread at a random position seems to be a perfect way to enter
an unspecified state for the program.
 
What if that thread is halfway through reallocating a vector?
Paavo Helde <eesnimi@osa.pri.ee>: Feb 07 12:23PM +0200

07.02.2023 11:25 Frederick Virchanza Gotham kirjutas:
 
 
> A well-written program should work properly 99.9% of the time.
So if our customer wants to analyze yet another batch of their 100,000
microscope images, the program would randomly fail on 100 images. Not a
great selling point.
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 07 05:46AM -0800

On Tuesday, February 7, 2023 at 9:48:24 AM UTC, Bo Persson wrote:
 
> So if our customer wants to analyze yet another batch of their 100,000
> microscope images, the program would randomly fail on 100 images. Not a
> great selling point.
 
 
I would consider what the estimated time is for the task. If one thread is processing 800 images, and if each image should take between 7 and 9 milliseconds, then the whole lot should take between 5.6 seconds and 7.2 seconds. After 10 seconds I can check if the thread is still responsive. After another 5 seconds I can kill it and discard all of its work.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 12:12PM -0800

>> d by any thread.
 
> Huh? If any thread can unlock a mutex then whats the point of having it in
> the first place?
 
The thread that locks a mutex MUST be the thread that unlocks it.
Period. If you need something different than that, use a binary
semaphore or something.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 12:14PM -0800

On 2/7/2023 5:46 AM, Frederick Virchanza Gotham wrote:
>> microscope images, the program would randomly fail on 100 images. Not a
>> great selling point.
 
> I would consider what the estimated time is for the task. If one thread is processing 800 images, and if each image should take between 7 and 9 milliseconds, then the whole lot should take between 5.6 seconds and 7.2 seconds. After 10 seconds I can check if the thread is still responsive. After another 5 seconds I can kill it and discard all of its work.
 
Humm... Are you just starting out with threading?
scott@slp53.sl.home (Scott Lurndal): Feb 07 01:27AM

>non-RAII things in low-level classes like
>std::condition_variable::wait() et al, so the application level code can
>be clean and RAII.
 
There are simple cases where that approach is sufficient. But as I
noted above, it is not suitable for all cases. I've found it (RAII) more
a hindrence than an aid in most real world (locking) cases. Either it forces
clumsy/exessive source code or it expands the size of the critical region; the former
hinders maintenance, the latter, performance. I'd much rather see explicit
lock/unlock calls used to minimize the critical region rather than having
every exit from a scope automatically releasing one or more locks.
 
While I tend to avoid nesting locks, there are many cases where they
make sense and for deadlock avoidance the order of acquisition and release
becomes key; something that RAII may not be suitable to control.
scott@slp53.sl.home (Scott Lurndal): Feb 07 01:34AM


>Yes it's RAII, and `std::unique_lock` is the standard library's RAII
>based wrapper for a mutex lock: it acquires a lock in its constructor.
 
>I wouldn't call the standard library's threading support misguided.
 
Threading and synchronization are cooperative capabilities. I was
specifically refering to using RAII for synchronization - while I was
brought up on pthreads, I certainly don't consider the standard
library's threading support 'misguided', nor did I say it was.
 
 
>Not because I know enough about the technical to evaluate it, but
>because I know that it's designed by some of the finest & best, and it
>worked fine for me.
 
I spent a decade on standards committees; compromise is a key
to completing a standard rather than technical excellence (or elegance).
 
 
>It uses a line continuation scheme that's specified in RFC 3676 section
>4.1, of putting a space at the end of a line as continuation symbol;
><url: https://www.ietf.org/rfc/rfc3676.txt>.
 
Which, as you point out, is not supported by a thirty-plus year old
news reading client like xrn. Personally, I prefer to see what I
wrote, rather than what someone somewhere thinks it should look like.
 
Someday I'll take the time to update it for UTF-8 and MIME support, multi-thread
it (a chore when using X11 libraries, the interactions with the display server
need to be isolated to a single thread), and add a local header cache.
 
Someday.
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 07 12:19AM -0500

On 2/6/23 16:35, Scott Lurndal wrote:
...
> I don't recall 'not', 'and' and 'or' being C++ keywords.
 
Table 1 in the C++ standard lists alternatives for many tokens:
<% {
%> }
<: [
:> ]
%: #
%:%: ##
and &&
bitor |
or ||
xor ^
compl ~
bitand &
and_eq &=
or_eq |=
xor_eq ^=
not !
not_eq !=
 
These go way back - "The Design and Evolution of C++" describes them. My
copy of "The C++ Programming Language" and the first version of the C++
standard have unfortunately both gone missing, so I can't confirm
whether they were introduced by that standard, or earlier.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Feb 06 09:41PM -0800

> copy of "The C++ Programming Language" and the first version of the C++
> standard have unfortunately both gone missing, so I can't confirm
> whether they were introduced by that standard, or earlier.
 
They're in the 1998 ISO C++ standard (2.5 [lex.digraph]).
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
Paavo Helde <eesnimi@osa.pri.ee>: Feb 07 08:55AM +0200

07.02.2023 03:27 Scott Lurndal kirjutas:
 
> While I tend to avoid nesting locks, there are many cases where they
> make sense and for deadlock avoidance the order of acquisition and release
> becomes key; something that RAII may not be suitable to control.
 
For that scenario there is std::scoped_lock (C++17) - "deadlock-avoiding
RAII wrapper for multiple mutexes".
 
It calls the std::lock() function which "Locks the given Lockable
objects lock1, lock2, ..., lockn using a deadlock avoidance algorithm to
avoid deadlock."
 
These quotes are from https://en.cppreference.com
 
It looks like that at least the committee thinks RAII and nested locks
are not contradictory.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Feb 07 07:42AM -0800


> On 2023-02-06 10:35 PM, Scott Lurndal wrote:
 
[...]
 
> format", which you can see in the posting's headers.
 
> Thus, looking at my posting in TB's usual view it's fine, but the raw
> posted text lines are wrapped.
 
Unfortunately some or many of those trailing spaces don't
survive getting to the client newsreader in the first place.
I've looked carefully. In many cases where the lines are
wrapped, the trailing spaces aren't there.
 
> Evidently your newsreader XRN (X news reader) or perhaps your version
> of that newsreader, doesn't support RFC 3676's flowed format.
 
I've looked at the raw input, before it ever gets processed by
the newsreader. On most of the wrapped lines, no trailing spaces.
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Feb 07 05:34PM +0100

On 2023-02-07 4:42 PM, Tim Rentsch wrote:
>> of that newsreader, doesn't support RFC 3676's flowed format.
 
> I've looked at the raw input, before it ever gets processed by
> the newsreader. On most of the wrapped lines, no trailing spaces.
 
That's not what I see; furthermore without trailing spaces the articles
would not be formatted correctly in Thunderbird's default view.
 
It may be a problem with the tool you use to inspect spaces
(highlighting the text by selecting it is an easy way to see spaces), or
it may be your newsreader.
 
I would guess that like Scott's XRN the Gnus 5.11, from 2007, may not
support modern flowed format. There is however a later version, 5.14
first released in 2013. But its a "development version", whatever that
means. <url: https://en.wikipedia.org/wiki/Gnus>
 
- Alf
scott@slp53.sl.home (Scott Lurndal): Feb 07 04:35PM

>> of that newsreader, doesn't support RFC 3676's flowed format.
 
>I've looked at the raw input, before it ever gets processed by
>the newsreader. On most of the wrapped lines, no trailing spaces.
 
XRN doesn't "process" the message, it simply displays it as is.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 12:11PM -0800

On 2/6/2023 10:55 PM, Paavo Helde wrote:
 
> It calls the std::lock() function which "Locks the given Lockable
> objects lock1, lock2, ..., lockn using a deadlock avoidance algorithm to
> avoid deadlock."
 
Iirc, it uses a retry and backoff algorithm. There is another way using
address based hash locks where the locks are sorted and duplicates are
removed. It always preserves a strict locking order. A thread can take
several locks without fear of deadlock:
 
https://groups.google.com/g/comp.lang.c++/c/sV4WC_cBb9Q/m/Ti8LFyH4CgAJ
 
 
 
Manu Raju <MR@invalid.invalid>: Feb 07 07:00PM

Some of you might be interested in this paper by Amazon Engineer:
 
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0342r1.pdf>
scott@slp53.sl.home (Scott Lurndal): Feb 07 07:39PM

>Some of you might be interested in this paper by Amazon Engineer:
 
><https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0342r1.pdf>
 
Removing sequence points from the C++11 and following standards was sure to bite.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Feb 07 11:51AM -0800

> Some of you might be interested in this paper by Amazon Engineer:
 
> <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0342r1.pdf>
 
From the paper:
 
auto start = chrono::high_resolution_clock::now();
auto result = fib(which);
auto end = chrono::high_resolution_clock::now();
...
 
I was surprised to discover that the program printed an elapsed time
of zero milliseconds on at least one compiler. Looking at the
generated code at https://godbolt.org/z/vY5d9bref revealed that the
compiler had reordered the code to get the end time prior to running
the calculation.
 
I'm surprised such a transformation would be legal.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Feb 07 12:00PM -0800


>><https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0342r1.pdf>
 
> Removing sequence points from the C++11 and following standards was
> sure to bite.
 
But C++11 still has this in [intro.execution]:
 
Every value computation and side effect associated with a
full-expression is sequenced before every value computation and side
effect associated with the next full-expression to be evaluated.
 
I would think that would make it illegal to reorder these statements
(quoted from the paper); the calls to now(), fib(), and now() are full
expressions.
 
auto start = chrono::high_resolution_clock::now();
auto result = fib(which);
auto end = chrono::high_resolution_clock::now();
 
It seems to me the author encountered a compiler bug, not a flaw in the
language.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
Bonita Montero <Bonita.Montero@gmail.com>: Feb 07 07:44AM +0100

Am 06.02.2023 um 08:11 schrieb Paavo Helde:
 
> This would basically introduce a limited notion of 'reference' in the C
> language, which would make the language more complex to teach and learn.
> That's the opposite to the goals C currently has.
 
References are easy to learn.
Paavo Helde <eesnimi@osa.pri.ee>: Feb 07 09:18AM +0200

07.02.2023 08:44 Bonita Montero kirjutas:
>> C language, which would make the language more complex to teach and
>> learn. That's the opposite to the goals C currently has.
 
> References are easy to learn.
 
Yes, in the same way one push-up is easy to do.
Muttley@dastardlyhq.com: Feb 07 09:24AM

On Mon, 06 Feb 2023 13:03:11 -0800
>effectively creates a context-specific keyword, which means the parser
>has to interact with the symbol table. (Historically, this is because
>typedefs were introduced relatively late in the evolution of C.)
 
Could it not cheat and simply treat a typedef as a kind of macro?
Tim Rentsch <tr.17687@z991.linuxsc.com>: Feb 07 07:50AM -0800

>>> and learn. That's the opposite to the goals C currently has.
 
>> References are easy to learn.
 
> Yes, in the same way one push-up is easy to do.
 
Great analogy. I tip my hat to you sir.
 
It's interesting to note that in his talk on cpp2, Herb Sutter
has abandoned references as a separate concept, because they
are too complicated. Instead what references are mostly used
for has been replaced by parameter passing modes.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Feb 07 11:08AM -0800

> On Mon, 06 Feb 2023 13:03:11 -0800
> Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
[...]
>>has to interact with the symbol table. (Historically, this is because
>>typedefs were introduced relatively late in the evolution of C.)
 
> Could it not cheat and simply treat a typedef as a kind of macro?
 
No, typedefs have scope, and a declaration in an inner scope can hide a
typedef in an outer scope.
 
#include <stdio.h>
int main(void) {
typedef int Integer;
{
int Integer = 10;
printf("Integer = %d\n", Integer);
}
// int Integer = 20; // would be a syntax error
}
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
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: