Ros Source Code Analysis (4)-roslaunch process monitoring (Pmon)

Source: Internet
Author: User
Tags data structures finally block join

A small feature in the roslaunch is similar to the service restart feature in the Android init process, and if the process is created with the Respawn property, it needs to be restarted after the process dead, which is a process monitoring role, and the relevant source code is located in pmon.py.

The following analysis of its main functions,

#ros_comm \tools\roslaunch\src\roslaunch\pmon.py
class Process (object): "" "
    Basic Process Representation for L{processmonitor}. Must is subclassed to
    provide actual start ()/stop () implementations.

    Constructor *must* is called from the Python Main thread in order for
    signal handlers to register properly. ""

    def __init__ (self, package, name, args, env,
            Respawn=false, respawn_delay=0.0, Required=false):
 properties of the #① process, Respawn is required to restart
        self.respawn = respawn
        self.respawn_delay = respawn_delay
        self.required = Required

The process () class is the base class that processmonitor () monitoring processes need to inherit, and you can set dead if the properties need to be restarted.

You can start a processmonitor process (thread) by calling the Start_process_monitor () function.

#① can have multiple pmon _pmons = [] _pmon_counter = 0 def start_process_monitor (): Global _pmon_counter If _shutting_down: #logger. Error ("Start_process_monitor:cannot start new Processmonitor (shutdown initiated)" ) return None _pmon_counter + = 1 name = "processmonitor-%s"%_pmon_counter logger.info ("Start_process_m Onitor:creating processmonitor ") #② Create Processmonitor Object process_monitor = processmonitor (name) Try: # p Revent race condition with Pmon_shutdown () being triggered # as we are starting a processmonitor (i.e. user hits C
        TRL-C # during startup) _shutdown_lock.acquire () #③ add Processmonitor object to _pmons and call its start () function _pmons.append (Process_monitor) Process_monitor.start () logger.info ("Start_process_monitor:processmoni Tor started ") Finally: _shutdown_lock.release () return process_monitor 
Class Processmonitor (Thread): Def __init__ (self, name= "Processmonitor"): thread.__init__ (self, name=name) #① monitored process self.procs = [] # #885: Ensure core procs Self.core_procs = [] def register (SE 
        LF, p): "" "Register process with L{processmonitor} @param p:process @type p:l{process} @raise rlexception:if process with same name is already registered "" Logger.info ("Processmonit
                or.register[%s] "%p.name) e = None with Self.plock:if self.has_process (p.name):
                E = Rlexception ("Cannot add process with duplicate name '%s '"%p.name) elif Self.is_shutdown: E = Rlexception ("Cannot add process [%s] after process Monitor have been shut down"%p.name) Else: #② register process with Pro
        Cessmonitor, which is the thread function added to the procs self.procs.append (p) #③processmonitor thread, Def run (self): "" " Thread routine of THe process Monitor. Note:you must still call Mainthread_spin or mainthread_spin_once () from the main thread in order to pick
        Up main thread work from the process Monitor. "" "Try: #don ' t let exceptions bomb thread, interferes with exit try:self . _run () finally:self._post_run () #④processmonitor thread function Body def _run (self): PLO
            CK = Self.plock Dead = [] respawn = [] #while循环, pmon off switch while not self.is_shutdown:
                        #监控中的进程 for P in Procs:try:if not p.is_alive (): 
                                Logger.debug ("process[%s" has died, respawn=%s, required=%s, exit_code=%s ", P.name,
                                "True (%f)"% p.respawn_delay if p.respawn else P.respawn, p.required, P.exit_code) exit_code_str= P.get_exit_description () #⑤ This process is necessary, the required process dead off, Pmon itself also closes #将self. Is_shu Tdown set to True if p.required:printerrlog (' = ' *80+ ' required process [%s] ] has died!\n%s\ninitiating shutdown!\n "% (p.name, exit_code_str) + ' = ' *80) Self.is_shutdown = Tr 
                        UE _respawn=[] for R in Respawn:try:if Self.is_shutdown:  Break if R.should_respawn () <= 0.0:printlog ("[%s] Restarting process "% r.name) # stop process, don ' t accumulate errors #⑥
                        Restarting the process that requires a restart, plays a role in process monitoring. R.stop ([]) R.start () Else: # Not ready yet, keep it ar Ound _respawn.append (R) except:traceback. Print_exc () logger.error ("Restart failed%s", Traceback.format_exc ()) respawn = _respawn  Time.sleep (0.1) #yield thread #moved this to finally block of _post_run #self. _post_run () #kill
 All processes

Discovered by the above code, Self.is_shutdown is the pmon shutdown switch, when Is_shutdown is true, then the while loop exits, will continue to execute _post_run (), will kill all the monitoring process, but in order, Finally kill the core process (Core_procs).

   def _post_run (self): Logger.info ("Processmonitor._post_run%s"%self) # This is already true entering, b
        UT go ahead and make sure Self.is_shutdown = True # Killall processes on run exit q = Queue () Q.join () with Self.plock: # make copy of Core_procs for threadsafe usage Core_procs

            = self.core_procs[:] Logger.info ("Processmonitor._post_run%s:remaining procs is%s"% (self, self.procs))
            # enqueue All Non-core procs in reverse order for parallel kill # #526/885:ignore core procs
        [Q.put (P) for p in reversed (Self.procs) if not p in Core_procs] # use workers killers = []  For I in range: t = _processkiller (q, i) killers.append (t) T.start () #
        Wait for workers-to-finish Q.join () shutdown_errors = [] # accumulate all the shutdown errors
For T in killers:            Shutdown_errors.extend (t.errors) del killers[:] # #526/885:kill Core Procs Last # we Don ' t want to parallelize this as the master have to is last for P in reversed (Core_procs): _kill_proc ESS (P, shutdown_errors) # delete everything except dead_list logger.info ("Processmonitor exit:cleaning u
            P Data structures and Signals ") with Self.plock:del core_procs[:] del self.procs[:]
            Del self.core_procs[:] reacquire_signals = self.reacquire_signals if reacquire_signals:

        Reacquire_signals.clear () logger.info ("Processmonitor Exit:pmon has shutdown") Self.done = True If Shutdown_errors:printerrlog ("Shutdown errors:\n" + ' \ n '. Join (["*%s"%e for E in shutdown_errors]))

through pmon.py code analysis, pmon.py must be in the main thread of a process to import, call Start_process_monitor () function will produce a pmon, and then the need to monitor the process (thread) Registering to Pmon, the main thread will have multiple Pmon saved in global _pmons = [].

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.