Tuesday, October 22, 2019

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

Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 22 02:09AM -0700

I'm working on an embedded Linux project.
 
When the computer boots up, a program called "Supervisor" is used to make sure that all background processes get immediately restarted if they crash.
 
So let's say a process called "gas_monitor" gets run at startup. If it crashes 3 days later, then Supervisor will immediately restart it.
 
Supervisor has limits though: If it tries to restart a process and it immediately crashes again, then it will try one more time to restart it, and then it will stop trying.
 
When the computer is configured a particular way, for example let's say we change the config file from "gas_source=alkane" to "gas_source=halogen", then the "gas_monitor" program no longer has a purpose.
 
Since "gas_monitor" is no longer needed, I can close it. . . but then Supervisor will try to restart it two more times, and it will close another two times. Then if the config file is changed back to "alkane", Supervisor won't try to restart the gas_monitor process because it's already failed the maximum times of two.
 
So when 'gas_monitor' isn't needed, I just need to put it to sleep. I want to do this the most efficient way possible (as I'm running embedded Linux and so CPU cycles are to be conserved).
 
Using C++11, I think the best way to do this is:
 
std::mutex m;
m.lock();
m.lock();
 
Am I right?
Paavo Helde <myfirstname@osa.pri.ee>: Oct 22 12:30PM +0300

On 22.10.2019 12:09, Frederick Gotham wrote:
> m.lock();
> m.lock();
 
> Am I right?
 
Nope, this is about the worst way to do that, if it appears to work then
it's accidental. Double-locking of a std::mutex in the same thread is
forbidden. From https://en.cppreference.com/w/cpp/thread/mutex :
 
"A calling thread must not own the mutex prior to calling lock or try_lock."
 
Also, when in infinite sleep your program won't wake up and continue to
work as expected, when the config file changes again.
 
Instead, what you can do is to set up an inotify disk monitor thread
which monitors the config file and notifies the main thread when the
config file changes. The main thread would wait in a
std::condition_variable::wait(); when notified, it would reread the
config file and decide if it should start running again or continue to
wait. I have no idea if your embedded Linux supports inotify.
 
Alternatively, you can set up another thread which handles the SIGHUP
signal via sigwait() and which notifies the main thread when the process
is sent a SIGHUP. The main thread will again wait in a
std::condition_variable::wait() meanwhile. This means that after
changing the config files one has to send the SIGHUP signal to the
process so it can reread the config and continue running or wait as desired.
Ian Collins <ian-news@hotmail.com>: Oct 22 10:36PM +1300

On 22/10/2019 22:09, Frederick Gotham wrote:
 
> So let's say a process called "gas_monitor" gets run at startup. If
> it crashes 3 days later, then Supervisor will immediately restart
> it.
 
Why don't you just run your processes as services?
> Using C++11, I think the best way to do this is:
 
> std::mutex m; m.lock(); m.lock();
 
> Am I right?
 
No! You can't re-lock a locked mutex.
 
--
Ian.
melzzzzz <mel@melzzzzz.com>: Oct 22 12:53PM +0200

Ian Collins <ian-news@hotmail.com> Wrote in message:r
> On 22/10/2019 22:09, Frederick Gotham wrote:> I'm working on an embedded Linux project.> > When the computer boots up, a program called "Supervisor" is used to> make sure that all background processes get immediately restarted if> they crash.> > So let's say a process called "gas_monitor" gets run at startup. If> it crashes 3 days later, then Supervisor will immediately restart> it.Why don't you just run your processes as services?> Using C++11, I think the best way to do this is:> > std::mutex m; m.lock(); m.lock();> > Am I right?No! You can't re-lock a locked mutex.
 
is there posibillity to specify recursive mutex? i recall there is
one?
 
 
--
Press any key to continue or any other to quit....
Paavo Helde <myfirstname@osa.pri.ee>: Oct 22 02:06PM +0300

On 22.10.2019 13:53, melzzzzz wrote:
>> On 22/10/2019 22:09, Frederick Gotham wrote:> I'm working on an embedded Linux project.> > When the computer boots up, a program called "Supervisor" is used to> make sure that all background processes get immediately restarted if> they crash.> > So let's say a process called "gas_monitor" gets run at startup. If> it crashes 3 days later, then Supervisor will immediately restart> it.Why don't you just run your processes as services?> Using C++11, I think the best way to do this is:> > std::mutex m; m.lock(); m.lock();> > Am I right?No! You can't re-lock a locked mutex.
 
> is there posibillity to specify recursive mutex? i recall there is
> one?
 
Yes there are recursive mutexes (which basically just encourage sloppy
coding).
 
However, OP wanted a deadlock (a very bad idea but that's what he
wanted), but a recursive mutex would not block if locked twice in the
same thread.
melzzzzz <mel@melzzzzz.com>: Oct 22 02:09PM +0200

Paavo Helde <myfirstname@osa.pri.ee> Wrote in message:r
"However, OP wanted a deadlock"
 
Strange, deadlock is a bug :)
 
--
Press any key to continue or any other to quit....
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Oct 22 01:30PM +0100

On Tue, 22 Oct 2019 02:09:16 -0700 (PDT)
> m.lock();
> m.lock();
 
> Am I right?
 
If you are writing multi-threaded embedded software professionally then
that is a somewhat alarming question.
 
The answer is no. You might get the deadlock you seem to want, or you
might not. The C++ standard doesn't specify what will happen, as double
locking a non-recursive mutex is a programming error. If you do get the
deadlock you seem to want then there is no way legal way of awakening
the thread should your configuration change (only the thread which
locks a mutex can properly unlock it).
 
Look up C++ condition variables, which would do what you want. Note
that these can spuriously awake, so put the check of the condition upon
which the wait occurs (which could just be a boolean value) in a while
loop.
scott@slp53.sl.home (Scott Lurndal): Oct 22 01:07PM

>I'm working on an embedded Linux project.
 
>When the computer boots up, a program called "Supervisor" is used to make s=
>ure that all background processes get immediately restarted if they crash.
 
In other words, you're recreating the almost 50 year old "init" daemon.
scott@slp53.sl.home (Scott Lurndal): Oct 22 01:09PM


>So when 'gas_monitor' isn't needed, I just need to put it to sleep. I want =
>to do this the most efficient way possible (as I'm running embedded Linux a=
>nd so CPU cycles are to be conserved).
 
kill( pid_of_gas_monitor, SIGSTOP );
 
when you're ready to continue the process:
 
kill (pid_of_gas_monitor, SIGCONT );
Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 22 12:28AM -0700

Is everybody now doing the following since C++11?
 
 
#include <type_traits>
#include <iostream>
 
int values[76];
 
auto main(void) -> int
{
//Old way
std::cout << sizeof(values)/sizeof(*values) << std::endl;
 
//New way
std::cout << std::extent<decltype(values)>::value << std::endl;
}
 
 
Or is there an even nicer way?
Ian Collins <ian-news@hotmail.com>: Oct 22 08:36PM +1300

On 22/10/2019 20:28, Frederick Gotham wrote:
> #include <iostream>
 
> int values[76];
 
> auto main(void) -> int
 
That is just so wrong..
 
> std::cout << std::extent<decltype(values)>::value << std::endl;
> }
 
> Or is there an even nicer way?
 
Use std::array.
 
--
Ian.
Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 22 12:38AM -0700

On Tuesday, October 22, 2019 at 8:36:49 AM UTC+1, Ian Collins wrote:
 
> > auto main(void) -> int
 
> That is just so wrong..
 
 
I already explained that I do this so that I know I'm not dealing with a C++03 compiler.
Ian Collins <ian-news@hotmail.com>: Oct 22 09:35PM +1300

On 22/10/2019 20:38, Frederick Gotham wrote:
 
>>> auto main(void) -> int
 
>> That is just so wrong..
 
> I already explained that I do this so that I know I'm not dealing with a C++03 compiler.
 
There are much better ways that don't involve C idioms..
 
--
Ian.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 22 10:56AM +0200

Use this:
 
template<typename T, int_t N>
std::size_t array_size( T (&at)[N] )
{
return N;
}
"Öö Tiib" <ootiib@hot.ee>: Oct 22 02:11AM -0700

On Tuesday, 22 October 2019 10:28:20 UTC+3, Frederick Gotham wrote:
> std::cout << std::extent<decltype(values)>::value << std::endl;
> }
 
> Or is there an even nicer way?
 
#include <array> // for array and also size since C++17
#include <iostream> // for cout

int main()
{
int legacy[76];
std::array<int,76> values;
 
// Since C++11
// there is ugly std::extent for legacy
std::cout << values.size() << std::endl;

// Since C++17 there is uniform way
std::cout << std::size(legacy) << std::endl;
std::cout << std::size(values) << std::endl;
}
"Öö Tiib" <ootiib@hot.ee>: Oct 22 02:18AM -0700

On Tuesday, 22 October 2019 10:38:48 UTC+3, Frederick Gotham wrote:
 
> > > auto main(void) -> int
 
> > That is just so wrong..
 
> I already explained that I do this so that I know I'm not dealing with a C++03 compiler.
 
That void there is redundant on any case and usenet posts do not document
in code that at least C++11 is expected.
Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 22 02:27AM -0700

On Tuesday, October 22, 2019 at 10:18:56 AM UTC+1, Öö Tiib wrote:
 
> > > > auto main(void) -> int

> That void there is redundant on any case and usenet posts do not document
> in code that at least C++11 is expected.
 
 
I put "extern" before function declarations, and I use 'void' instead of empty parentheses in function declarations and definitions so that it doesn't look like a function call.
Ian Collins <ian-news@hotmail.com>: Oct 22 10:33PM +1300

On 22/10/2019 22:27, Frederick Gotham wrote:
 
> I put "extern" before function declarations, and I use 'void' instead
> of empty parentheses in function declarations and definitions so that
> it doesn't look like a function call.
 
That makes no sense a all...
 
--
Ian.
"Öö Tiib" <ootiib@hot.ee>: Oct 22 02:35AM -0700

On Tuesday, 22 October 2019 12:27:56 UTC+3, Frederick Gotham wrote:
 
> > That void there is redundant on any case and usenet posts do not document
> > in code that at least C++11 is expected.
 
> I put "extern" before function declarations, and I use 'void' instead of empty parentheses in function declarations and definitions so that it doesn't look like a function call.
 
Huh. How can either "auto main() -> int" or "int main()" possibly look
like function call?
Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 22 03:54AM -0700

On Tuesday, October 22, 2019 at 10:35:33 AM UTC+1, Öö Tiib wrote:
 
> > I put "extern" before function declarations, and I use 'void' instead of empty parentheses in function declarations and definitions so that it doesn't look like a function call.
 
> Huh. How can either "auto main() -> int" or "int main()" possibly look
> like function call?
 
 
I will admit that I put the 'void' in there to make it ever so slightly more grotesque in nature to the people who find it grotesque in the first place.
 
I find this situation quite similar to rollerblades and quad skates. Personally I don't want to go on quad skates but I don't mind people being on quad skates around me. Myself though I bought a pair of Kaze 110mm three-wheelers last month.
 
I could make similar comparisons.
Bonita Montero <Bonita.Montero@gmail.com>: Oct 22 01:05PM +0200

> There are much better ways that don't involve C idioms..
 
The advantages of std::array over a C-stype array are insignificant.
melzzzzz <mel@melzzzzz.com>: Oct 22 02:11PM +0200

Bonita Montero <Bonita.Montero@gmail.com> Wrote in message:r
> > There are much better ways that don't involve C idioms..The advantages of std::array over a C-stype array are insignificant.
 
Except you can't pass c array as array, for that, you need
struct... therefore array struct...
--
Press any key to continue or any other to quit....
Bonita Montero <Bonita.Montero@gmail.com>: Oct 22 02:29PM +0200

> Except you can't pass c array as array, for that, you need
> struct... therefore array struct...
 
I think no one has missed that feature so far.
And it's very inefficient.
scott@slp53.sl.home (Scott Lurndal): Oct 22 01:05PM


>Is everybody now doing the following since C++11?
 
No, the old way will continue to work forever and is
much more readable.
Frederick Gotham <cauldwell.thomas@gmail.com>: Oct 21 11:56PM -0700

> server doesn't know of any newsgroup whose name contains "Boost", but
> there are apparently mailing lists:
> <https://www.boost.org/community/groups.html>.
 
 
I emailed the IT guy in my job just now to ask if he'll let me access the Gmane news server to get at those mailing lists.
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: