Tuesday, February 7, 2023

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

"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 12:22PM -0800

On 2/7/2023 1:48 AM, Bo Persson wrote:
>> 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.
 
It's horrible. Well, I had to deal with robust mutexes many moons ago.
If a processed dies while holding a mutex, we can try to recover and
repair its state:
 
https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html
 
Windows even has WAIT_ABANDONED.
 
Have fun! It can be done, but is it not exactly, fun...
 
 
 
> What if that thread is halfway through reallocating a vector?
 
Yikes!
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 07 02:17PM -0800

On Tuesday, February 7, 2023 at 8:22:37 PM UTC, Chris M. Thomasson wrote:
 
> It's horrible. Well, I had to deal with robust mutexes many moons ago.
 
 
I've worked with robust mutexes in Linux; if the thread that acquired the lock dies, the lock is released.
 
However I'm trying to accommodate a situation in which a worker thread freezes -- the thread's still alive but it's caught in an infinite loop or a blocking function won't return.
 
In your previous post you said that the thread that unlocks a mutex must be that one had locked it ... well I'll use an atomic_flag like I described in the link I gave in my original post.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 02:24PM -0800

On 2/7/2023 2:17 PM, Frederick Virchanza Gotham wrote:
> On Tuesday, February 7, 2023 at 8:22:37 PM UTC, Chris M. Thomasson wrote:
 
>> It's horrible. Well, I had to deal with robust mutexes many moons ago.
 
> I've worked with robust mutexes in Linux; if the thread that acquired the lock dies, the lock is released.
 
No. Not threads. Processes. If a thread dies in a process it will take
down the whole process.
 
 
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 02:28PM -0800

On 2/7/2023 2:17 PM, Frederick Virchanza Gotham wrote:
 
> I've worked with robust mutexes in Linux; if the thread that acquired the lock dies, the lock is released.
 
> However I'm trying to accommodate a situation in which a worker thread freezes -- the thread's still alive but it's caught in an infinite loop or a blocking function won't return.
 
> In your previous post you said that the thread that unlocks a mutex must be that one had locked it ... well I'll use an atomic_flag like I described in the link I gave in my original post.
 
Huh? Are you creating a mutex or a binary semaphore? They are quite
different.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 02:49PM -0800

On 2/7/2023 2:24 PM, Chris M. Thomasson wrote:
 
>> However I'm trying to accommodate a situation in which a worker thread
>> freezes -- the thread's still alive but it's caught in an infinite
>> loop or a blocking function won't return.
[...]
 
That is a lot different than a thread up and crashing in a process. Why
do you think a mutex would help you with that? Something reeks of a bad
design. Using robust mutexes for a single process does not make any
sense at all.
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 07 02:51PM -0800

On Tuesday, February 7, 2023 at 10:24:47 PM UTC, Chris M. Thomasson wrote:
 
> No. Not threads. Processes. If a thread dies in a process it will take
> down the whole process.
 
I used the following function:
 
https://man7.org/linux/man-pages/man3/pthread_mutexattr_setrobust.3.html
 
Here's an excerpt:
 
"The robustness attribute specifies the behavior of the mutex when the owning thread dies without unlocking the mutex."
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 02:53PM -0800

On 2/7/2023 1:25 AM, Frederick Virchanza Gotham wrote:
 
> 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".
 
You might be interested in cancellation points and pthread_cancel, but
its a bitch and a half to use. asynchronous or deferred canceling. There
are better ways. Start with the actual design. asynchronous
cancelability should be avoided at all costs! deferred makes more sense,
but still...
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 02:53PM -0800

On 2/7/2023 2:51 PM, Frederick Virchanza Gotham wrote:
 
> https://man7.org/linux/man-pages/man3/pthread_mutexattr_setrobust.3.html
 
> Here's an excerpt:
 
> "The robustness attribute specifies the behavior of the mutex when the owning thread dies without unlocking the mutex."
 
If the owning thread dies, it means the process has died. robust mutexes
are for inter process sync.
scott@slp53.sl.home (Scott Lurndal): Feb 07 11:01PM


>> "The robustness attribute specifies the behavior of the mutex when the owning thread dies without unlocking the mutex."
 
>If the owning thread dies, it means the process has died. robust mutexes
>are for inter process sync.
 
The owning thread could exit (or be cancelled) without releasing the mutex
and without killing the process.
 
That said, I think the application should be designed such that robust
mutexes are not required; Just because a robust mutex automatically
becomes unlocked - that doesn't prevent the state protected by the mutex
from being partially updated and hence buggy when the robust mutex was released.
 
If the dead thread had been in the middle of a linked list update, for
example, the list could end up with a loop or sans a bunch of entries.
David Brown <david.brown@hesbynett.no>: Feb 07 11:16PM +0100

On 07/02/2023 20:51, Keith Thompson wrote:
> compiler had reordered the code to get the end time prior to running
> the calculation.
 
> I'm surprised such a transformation would be legal.
 
(Note - I haven't read the paper yet, just this post.)
 
It seems perfectly reasonable to me. Neither C nor C++ care about
timing, nor the ordering of anything except observable behaviour. The
compiler can see that "fib" does not have any observable behaviour - it
is a "pure" function. It doesn't matter when the calculation is done,
as far as the observable behaviour is concerned, so it is fine to move
it before or after the calls to now() if that gives more efficient code.
 
It would also be fine for the compiler to pre-calculate fib(42) at
compile time and skip the run-time calculation entirely.
 
I see this kind of misunderstanding regularly when people try to make
benchmarks. Usually the solution is to put "volatile" in the right
place - force observable behaviour to force the ordering by making
"which" and "result" volatile.
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: