How to prevent subprocess.popen to "get lost" in Windows? - python

I have a somehow curious Python(3.x) problem:
Basically i just want to create a timer which calls an external program (.exe) at a predefined time - (simplified below, additionally there is a countdown output):
time.sleep(y)
x=popen("pathto.exe")
If i test my code everything works exactly as i want BUT only for small y. For large y (wait for more than a few hours), Python doesnt execute the popen command (but there arent any Errors as well). Any other "normal" code after the popen command (for example an Email notification in my case) works fine.
Im not entirely sure if this is a Windows (im working on 64bit Windows 7, disabled all energy saving features im aware of) or a Python problem but couldnt find a solution so far:
I tried several additional arguments for popen (Shell/no Shell, etc.) and tried to open the program/define X ahead of the waiting period and close it afterwards again but nothing solved this unfortunately.
Many Thanks!
Edit: more detailed code example:
while 1:
if time.mktime(trade2)<=time.time():
break
else:
dif=time.mktime(trade2)-time.time() # this is just for a visible countdown
aus=time.gmtime(dif)
sys.stdout.flush()
print("\b\b\b\b\b\b\b\b\b", end="\r")
print(aus[3],aus[4],aus[5], sep=":",end="")
time.sleep(0.5)
x=subprocess.Popen("c:/xyz/abc.exe")
print("Sending Mail...")
The print() is ALWAYS executed as expected, the Popen only when the countdown less than approx 1-2hours.

Sleep does not have a guaranteed wake up time. According to the docs sleep may last a longer or shorter amount of time than requested. I've answered this question before on SO, with alternatives.

Related

Implementing a dead man's switch for running code

I have some Python code that's a bit buggy. It runs in an infinite loop and I expect it to print something about once every 50 milliseconds, but sometimes it hangs and stops printing or even outright segfaults. Unfortunately, the problem seems to be fairly rare, so I've had trouble nailing down the exact cause of the issue. I want to have the code up and running while I debug the problem, so while I try to figure it out, I'd like to create a dead man's switch that runs my code, but stops if the code doesn't print anything in a certain time frame (say, 5 seconds) or exits and finally executes a command to notify me that something went wrong (e.g. 'spd-say terminated').
I put this into the terminal for my first attempt at this:
python alert.py; spd-say terminated;
Unfortunately, it didn't seem to work - at this point I realized that the code was not only crashing but also hanging (and I'm also not sure whether this would even work if the code crashes). Unfortunately, I'm not very familiar with bash yet (I assume that's what I'm using when I run stuff in the terminal), and I'm not sure how I could set up something like what I want. I'm also open to using other things besides bash to do this if it would be particularly difficult to do for some reason.
What would be the best way to implement what I want to do?
You could run two python programs with a pipeline between them. On one side you have you buggy script writing something on the pipeline every less than 5 seconds. On the receiving end of the pipeline you have a very simple script that checks how long it has been since it last received anything. If this time is more than 5 seconds.
This way you decouple your watchdog from your buggy script.

If I Keyboard Interupt a running Python script, is there a way to begin again where it left off? (windows)

I have a long-running script at work (windows unfortunately) where I programmed it to print the current analysis results if I ctrl-c. However, I was curious if after doing ctrl-c, I could start the script running again where it left off?
This is actually 3 questions:
-is it possible to do this without any programming changes? - e.g. I accidentally hit ctrl-c and want to retroactively start it where it left off
-can I use a command like ctrl-z (only on Mac I believe) on windows and program the script to print results when I issue it?
-what is the best programmatic way of automatically finishing the execution of the line I am on (massive .txt file of data) when I use an interrupt command, store that line number (in a file maybe), and restart the program on the next line with the next execution?
Thanks!
(FYI: I'm a novice Pythoner and my script currently takes about 10 min to perform 1 million lines. Files I will use in the future will often have 100+ million lines)
The short answer to your first question is No. Ctrl-C signals the interpreter, which unwinds the stack, presents you with a stack trace, and halts. You can't recover from ctrl-C for the same reason that you can't recover from any other untrapped exception. What you are asking for is a quick way to put Humpty Dumpty back together again.
You can restart a chess game from any point simply by laying out the pieces according to a picture you made before abandoning the game. But you can't easily do that with a program. The problem is that knowing the line number where the program stopped is not nearly enough information to recreate the state of the program at the time: the values of all the variables, the state of the stack, how much of the input it had read, and so forth. In other words, the picture is complicated, and laying out the pieces accurately is hard.
If your program is writing to the Windows console, you can suspend output by pressing ctrl-S and restart it by pressing ctrl-Q. These control characters are holdovers from the days of Teletype machines, but modern terminal emulators still obey them. This is a quick way to do what you want without program changes. Unsophisticated, but maybe good enough to begin with.
And your program will probably run a lot faster if it writes its output to file, for later examination in a text editor, rather than writing directly to the Windows console.
A full-on solution to your problem is something that I hesitate to recommend to a novice. The idea is to split calculation and display into two processes. The calculation process does its thing and feeds its results line by line to the display process. The display process listens to the calculation process and puts the results that it gets on the screen, but can also accept pause and resume commands. What happens while it is in the paused state is a design decision. You can decide either that the calculation process should block (easier option) or that it should buffer its results until the display process is ready to accept them again (harder option).

Printing in thread not working for python 3

For some reason I keep failing to create a simple thread using python 3, the code below prints "test" once and then leaves the program running without printing anymore lines.
import time, threading
def test():
print("test")
threading.Timer(1, test).start()
test()
This code seems to work for millions of others, but not for me.
I'm not sure if this is just a printing failure or if the thread is not running at all. I've found and tried dozens of examples like the one above but they all give me the same issue (also time.sleep() has the same issue). I figure I might have to cancel the threading before I start a new one, but this has proven to be kind of difficult during a loop and I am not even sure that will work.
I found the solution to my problem, I was using git bash and apperently it doesn't show values when printing them in a loop so it would only print the first time the function was called. It works fine using windows CMD.

Python help - Need the ability to restart the script when it hangs or automatically set a timer

I currently have a python script that does exactly what I need it to do, however every now and then the script will hang and the only way to restart it is by killing the script and relaunching it.
I was wondering if there was a way to put in a few commands that will restart it lets say everytime it hangs or when a specific message appears or even just restart it on a timer eg:every 50 seconds.
I cannot provide the code through here, but I can provide it if we talk in private.
I am willing to pay you a bit of money if your fix does work.
please email me at stackoverflow1#shaw.ca
Thanks!
Edit: I see, ok - then is it possible to provide me with some codes which it will restart on a specific timer?
Edit2: Ok thanks everyone for their comments - I will get in touch with the person who built it to see if they can rewrite it from scratch to include a timer.
Cheers.
Feel free to pay me if you want, although it is by no means necessary.
Here:
import time
import threading
import os
def restart():
time.sleep(50)
os.execv('/full/path/to/this/script', ['second argument', 'third argument'])
def main():
t = threading.Thread(target=restart, args=(), name='reset')
t.start()
# ... The rest of your code.
If you have any buffers open that you care about (such as stdout) you'll want to flush them right before the call to execv up there.
I haven't tested this code, because I don't have a python interpreter handy at the moment, but I'd be surprised if it didn't work. That call to execv replaces the current context, so you don't get an increasingly deep hierarchy of child processes. All I'm doing, in case you're curious and want to know what magic phrase to google, is setting a "timer interrupt handler". For the pedants, no, I recognize this thing isn't directly handling any interrupts.
The numeric argument to sleep is in seconds. I would simply request that you not use my code in malware, unless it is for research purposes. I'm particular that way.
edit: Additionally, a lot of it was taken from here.

debugging: how to check what where my Python program is hanging?

A fairly large Python program I write, runs, but sometimes, after running for minutes or hours, in a non easily reproducible moment, hangs and outputs nothing to the screen.
I have no idea what it is doing at that moment, and in what part of code it is.
How can I run this in a debugger or something to see what lines of code is the program executing in the moment it hangs?
Its too large to put "print" statements all over the place.
I did:
python -m trace --trace /usr/local/bin/my_program.py
but that gives me so much output that I can't really see anything, just millions of lines scrolling on the screen.
Best would be if I could send some signal to the program with "kill -SIGUSR1" or something, and at that moment the program would drop into a debugger and show me the line it stopped at and possibly allow me to step through the program then.
I've tried:
pdb usr/local/bin/my_program.py
and then:
(Pdb) cont
but what do I do to see where I am when it hangs?
It doesn't throw and exception, just seems like it waits for something, possibly in an infinite loop.
One more detail: when the program hangs, and I press ^C and then (not sure if that is necessary) the program continues normally (without throwing any exception and without giving me any hint on the screen why did it stop).
This could be useful to you. I usually do
>>> import pdb
>>> import program2debug
>>> pdb.run('program2debug.test()')
I usually add a -v option to my programs, which enables tons of print statements explaining what I'm doing in detail. When you write a program in the future, consider doing the same before it gets thousands of lines big.
You could try running it in debug mode in an IDE like pydev (eclipse) or pycharm. You can break the program at any moment and get to its current execution point.
No program is ever too big to put print statements all over the place. You need to read up on the logging module and insert lots of logging.debug() statements. This is just a better form of print statement that outputs to a file, and can be turned off easily in production software. But years from now, when you need to modify the code, you can easily turn it all back on and get the benefit of the insight of the original programmer.

Categories