1

I'm running a Python code in a Raspberry Pi 4 which reads signals from certain pins and responds accordingly.

On this function, after multiple prints in between lines, I narrowed the problem to (apparently) a sleep() call.

def on_enter_sanitizing(self):
    try:
        print('Entered state: Sanitizing')
        self.setLevelLedCallbacks() #This function has a print at the end, which shows
        sleep(0.8)
        print("POST SLEEP") #This print doesn't show
        level = self.checkForLevel()
        print('Sanitizing with level: '+level)
        self.BUTTON_PLAY_OUT.Press()
        self.setErrorLedCallbacks()
        errors = False
        while True:
            sleep(0.3)
            if self.checkEndCondition():
                break
            if self.checkForErrors():
                errors = True
                break
        self.cancelLevelCallbacks()
        self.cancelErrorLedCallbacks()
        if errors:
            self.error_mid_san()
        else:
            print("SANITIZATION OK")
            self.sanitizationFinished()
    except Exception as e:
        print("ERROR")
        print(e)

The try/except block was added to check for an Exception, but it doesn't trigger the "except" block. At one point I also added a print just before the sleep, which also showed.

The terminal, aside from any output before that sleep shows nothing when exiting, just like any code would do when finishing execution.

As background, I have some callbacks to certain Raspberry pin edges (using the pigpio module) and certain Timer objects running in the background (from the threading module). There are no exit calls in the code, so there is no reason why the code wouldn't continue onto the next lines. Also, a very similar function to this runs at some point before in the code just fine.

I don't know how else I can debug the code. Any help is greatly appreciated and any additional information I will be happy to provide.

EDIT (As I answer comments):

  1. Sleep is correctly imported at the top, there are sleep calls before this function runs that execute correctly.

  2. Because it was requested in the comments, this is the code for setLevelCallbacks:

    def setLevelLedCallbacks(self):
      self.pin_callback(self.PIN_L1,self.LED_L1.asyncRead(),None)
      self.LED_L1.setCallback(Either=self.pin_callback)
      self.pin_callback(self.PIN_L2,self.LED_L2.asyncRead(),None)
      self.LED_L2.setCallback(Either=self.pin_callback)
      self.pin_callback(self.PIN_L3,self.LED_L3.asyncRead(),None)
      self.LED_L3.setCallback(Either=self.pin_callback)
      print("CALLBACK COMPLETE") #This shows
    

The callback is called once before it is set because I need an initial value before any edge.

EDIT 2:

  1. I tried some things recommended in the comments: Commented out the self.setLevelCallbacks() line before the sleep, still exited
  2. Used sys.stdout.flush() after every print
  3. Checked with htop and saw no abnormal behaviour
  4. Printed a line right before the sleep and that shows.
  • If `errors` is true and no exceptions are raised, then this code won't print anything after the `Sanitizing` message. – John Gordon Jan 15 '22 at 01:28
  • @JohnGordon The code exits way before that, on the sleep before the "POST SLEEP" print – Sebastian Araneda Jan 16 '22 at 18:06
  • Well, that's odd. Maybe the try/except is interfering somehow? Try taking out the try/except statements. Also try putting `sys.stdout.flush()` after each print. – John Gordon Jan 16 '22 at 20:20
  • @JohnGordon I put the try/except after I detected this problem to check if it was an excepction the reason of the unexpected exit. Without it it has the same problem. I'll try the second one. – Sebastian Araneda Jan 17 '22 at 16:46
  • @SebastianAraneda Can you also post the code of setLevelLedCallbacks()? – BhavinT Jan 17 '22 at 17:16
  • Sure, I'll add it as en Edit, one sec. – Sebastian Araneda Jan 17 '22 at 17:17
  • Ok I'm having some issues making Stack Overflow recognize the code, there's the plaintext version – Sebastian Araneda Jan 17 '22 at 17:23
  • Can you also print something after self.setLevelCallbacks in on_enter_sanitizing to validate that function returned back after executing @SebastianAraneda – BhavinT Jan 17 '22 at 17:28
  • Sure, I'll need about 1hr to set up the Pi and the components again and I can get back to you. I'm 99% sure that debugging this last friday I tried that with a "PRE SLEEP" print before the sleep and it showed. – Sebastian Araneda Jan 17 '22 at 17:31
  • For debugging, I'd temporarily set the `sleep(0.8)` to a large value `sleep(30)` and see if it terminates immediately or after 30 seconds. Also, try running program as sudo. In bash, you can precede the command to run your script with `time` to get an overall assessment of how long it takes as in `time `. It may be valuable to know how you are executing the script - is it in a subprocess where the parent process terminates? – Computable Jan 18 '22 at 17:52
  • Hi! I've set up the sleep to larger times and it closes immediately when getting to the line. I'm running the code with sudo python code.py. Trying the stuff from comments I'm in doubt if it is the "sleep" call or something from one of the libraries I'm importing. – Sebastian Araneda Jan 19 '22 at 18:05
  • Can you add the source for `self.checkForLevel()` ? – Ramon Moraes Jan 22 '22 at 13:23
  • @SebastianAraneda check if your process is receive some sort of signal(https://stackabuse.com/handling-unix-signals-in-python/). Perhaps you are receiving something from the OS that might be able to indicate what is going on – K. Shores Jan 24 '22 at 04:25

2 Answers2

0

Possibly you should check your remaining code, where you use yours Timers, if they wait correctly for thread executing mentioned code.

If this try clause does not catch exception, there could be possibility that thread is terminated or stopped by its parent. Also, if parent process finishes before this thread, it will not give the thread time to finish cleanly. It is common issue with multithreaded apps, as well as apps terminated from terminal using i.e. kill -9.

Maciej Wrobel
  • 640
  • 4
  • 11
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 18 '22 at 12:42
  • I've thought of this scenario, but this function runs on the main Thread. Is there a way for a child Thread to stop the main one? (without any specific calls for this or any intention to do so) – Sebastian Araneda Jan 19 '22 at 17:53
-1

That isn't how you sleep, You need to import the time module.

import time

time.sleep(0.8) # Sleep for 8 seconds

About python sleep

Python docs on Sleep

You can also use python Asynchronous I/O

Wakka
  • 426
  • 1
  • 9
  • You can use sleep(0.8) if you import like this ``` from time import sleep``` @Wakka – BhavinT Jan 17 '22 at 17:10
  • and @Wakka if there is import error it will be displayed on the stdout but here that's not the case – BhavinT Jan 17 '22 at 17:12
  • @BhavinT, you downvoted me to point that out? You are also assuming he has imported anything. His code also breaks at sleep...... – Wakka Jan 17 '22 at 17:14
  • I didn't downvoted you @Wakka – BhavinT Jan 17 '22 at 17:14
  • This function is only part of my code, the sleep is imported on the top. Also there are multiple sleep calls before that work as expected. – Sebastian Araneda Jan 17 '22 at 17:15
  • @SebastianAraneda can you provide an example of your docs head so we can see all your imports? – Wakka Jan 17 '22 at 17:18
  • @SebastianAraneda Also can you try replacing that particular sleep with wait? – Wakka Jan 17 '22 at 17:19
  • You mean like it's used in this post? https://stackoverflow.com/questions/29082268/python-time-sleep-vs-event-wait – Sebastian Araneda Jan 17 '22 at 17:27
  • @SebastianAraneda I was thinking wait via OS – Wakka Jan 17 '22 at 17:35
  • If it doesn't make the Timer threads I mentioned in the post sleep as well, yeah, I can try and it shouldn't be an issue – Sebastian Araneda Jan 17 '22 at 17:36
  • @SebastianAraneda have you encountered any memory leaks by any chance? – Wakka Jan 17 '22 at 17:42
  • @Wakka how can I check for those? Nothing shows in console when exiting. – Sebastian Araneda Jan 17 '22 at 17:44
  • @SebastianAraneda use htop in terminal then run the code. If the numbers get a bit mad and your script is using a load of resources and things just generally slow down then might have to check for memory leaks. pin_callback has been known to go a bit overboard. But I thought it was pin.callback? – Wakka Jan 17 '22 at 17:48
  • I'll try that in a few (among all the other things you requested). To clarify on the pin_callback thing. I have children objects to interact with the pins, and pin_callback is a function defined in the parent object that I set as callback to all children and stores the value of the pin in a dictionary in the parent object – Sebastian Araneda Jan 17 '22 at 18:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241150/discussion-between-sebastian-araneda-and-wakka). – Sebastian Araneda Jan 17 '22 at 19:26