@@ -70,21 +70,21 @@ def wait(self):
7070 """
7171 if self ._previous is None :
7272 with self ._lock :
73- self ._previous = time .time ()
73+ self ._previous = time .monotonic ()
7474 while True :
7575 try :
7676 with self ._lock :
77- if time .time () - self ._previous > self ._period :
77+ if time .monotonic () - self ._previous > self ._period :
7878 break
7979 for interrupt in self ._interrupts :
8080 if interrupt ():
81- self ._previous = time .time ()
81+ self ._previous = time .monotonic ()
8282 return
8383 time .sleep (1.0 / self ._core_frequency )
8484 except KeyboardInterrupt :
8585 self ._keyboard_interrupted = True
8686 break
87- self ._previous = time .time ()
87+ self ._previous = time .monotonic ()
8888
8989
9090def _clearer_error_message (e : Exception ) -> str :
@@ -335,7 +335,10 @@ def _frequency_iterate(self) -> None:
335335 self ._frequency_iterate_error (e , True )
336336 else :
337337 self ._status .state (State .running )
338- self ._status .activity ("sleep" )
338+ try :
339+ self ._status .activity ("sleep" )
340+ except Exception as e :
341+ self ._frequency_iterate_error (e , False )
339342 try :
340343 self .wait ()
341344 except Exception as e :
@@ -388,9 +391,12 @@ def stop(self, blocking: bool = False) -> None:
388391 self ._monitor_stop (self ._on_stop , blocking )
389392
390393 def alive (self ) -> bool :
391- if self ._thread is None or not self ._thread .is_alive ():
394+ try :
395+ if self ._thread is None or not self ._thread .is_alive ():
396+ return False
397+ return True
398+ except Exception :
392399 return False
393- return True
394400
395401 def revive (self ):
396402 while self .alive ():
@@ -449,7 +455,7 @@ def start(self):
449455 self ._starting = True
450456 self ._running .value = True
451457 with self ._manage_starting ():
452- if self ._status .state != State .error :
458+ if self ._status .get_state () != State .error :
453459 self ._status .state (State .starting )
454460 self ._process = Process (
455461 target = self .run ,
@@ -470,8 +476,11 @@ def stop(self, blocking: bool = False) -> None:
470476 def alive (self ) -> bool :
471477 if self ._process is None :
472478 return False
473- self ._process .join (timeout = 0.1 )
474- return self ._process .is_alive ()
479+ try :
480+ self ._process .join (timeout = 0.1 )
481+ return self ._process .is_alive ()
482+ except Exception :
483+ return False
475484
476485 def revive (self ):
477486 self ._starting = True
@@ -486,6 +495,9 @@ def revive(self):
486495
487496 def run (self , memories : Dict [str , DictProxy ], running : MpValue ) -> None :
488497 SharedMemory .set_all (memories )
498+ # Reinitialize the _Sleeper lock in the child process to avoid
499+ # potential deadlock from inheriting a locked copy after fork.
500+ self ._lock = threading .Lock ()
489501 # note: running.value set to True by start and revive
490502 while running .value : # type: ignore
491503 try :
0 commit comments