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:
Post a Comment