atexit not writing to file - python

I'm testing to see if the atexit module runs properly by attempting to print to file. The actual purpose of atexit will be to close the open port, however this is to test if atexit is working in the first place. However, atexit is not printing to file, any ideas why not? Any help is appreciated.
import atexit
import scala5
from scala5 import sharedvars
scalavars = sharedvars()
import serial
myPort=serial.Serial()
myPort.baudrate = 9600
myPort.port = "COM4"
myPort.parity=serial.PARITY_NONE
myPort.stopbits=serial.STOPBITS_ONE
myPort.bytesize=serial.EIGHTBITS
myPort.timeout=2
myPort.writeTimeout=2
try:
myPort.close()
except:
print("didn't need to close")
def port_exit():
fo = open("test.txt", "w")
fo.write("This works!")
fo.close()
myPort.open()
while True:
x = myPort.readline()
if x == "1\r\n":
scalavars.door = x
scala5.ScalaPlayer.Sleep(10)
atexit.register(port_exit)
port_exit()

You are registering the function after your while loop, which I am assuming you are exiting by killing the script (meaning the function port_exit isn't registered). If you register the function before the while then it should trigger and write the file when the script exits.
atexit.register(port_exit)
while True:
x = myPort.readline()
if x == "1\r\n":
scalavars.door = x
scala5.ScalaPlayer.Sleep(10)

Related

Python: How to resume the python script as soon as vpn network is up?

I have a python script (xyz.py) that I run through the command prompt. My question is that don't we have any method which helps to resume the python code automatically from where it was lost the VPN connection, without any manual intervention. This will help to avoid monitoring the code frequently. Below is my code but it reads from the start if there is any disconnection. Please suggest.
filename = 'xyz.py'
while True:
p = subprocess.Popen('python '+filename, shell=True).wait()
""" #if your there is an error from running 'xyz.py',
the while loop will be repeated,
otherwise the program will break from the loop"""
if p != 0:
continue
else:
break
If me, time.sleep will be used:
import os
import time
from datetime import datetime
import requests
script = 'xyz.py'
def main():
network_check_url = 'http://8.8.8.8'
while True:
try:
requests.get(network_check_url)
except Exception as e:
print(datetime.now(), e)
time.sleep(1)
else:
print('Network is ok. {datetime.now():%Y-%m-%d_%H:%M:%S}')
os.system(f'python {script}')
return
if __name__ == '__main__':
main()

How to write to named pipe with the threading module in Python?

I am trying to write a program which communicates to an external program through named pipes. The python script does not know when the external program opens up the named pipe/file for reading, so the python script need to open the pipe in blocking mode, see open. If the python script opens in non-blocking mode and the external program has not opened for reading, the open statement will result in an error.
So to open in blocking mode, the python script could open the named pipe in a separate thread, and I have tried the threading module. In the below example I just read from the named pipe in the main thread, but it produces the same error:
import threading
import os
pipe_name = 'pipe_test'
class WriterNamedPipe(threading.Thread):
def __init__(self, filepath, input):
'''
Write: generate that will output each line of input
'''
# Inherit
threading.Thread.__init__(self, verbose = True)
self.daemon = False
self.filepath = filepath
self.input = input
self.start()
def run(self):
# Open blockingly
with open(self.filepath, 'w') as f:
f.write(self.input)
if not os.path.exists(pipe_name):
os.mkfifo(pipe_name)
WriterNamedPipe(pipe_name, '1\n' * 100)
with open(pipe_name, 'r') as f:
print f.read()
This would results in a hang/freeze:
MainThread: <WriterNamedPipe(Thread-1, initial)>.start(): starting thread
Thread-1: <WriterNamedPipe(Thread-1, started 1078922160)>.__bootstrap(): thread started
Thread-1: <WriterNamedPipe(Thread-1, started 1078922160)>.__bootstrap(): normal return
Compilation hangup
However, a similar example from here works, but with os.fork:
import os, time, sys
pipe_name = 'pipe_test'
def child( ):
pipeout = os.open(pipe_name, os.O_WRONLY)
counter = 0
while True:
time.sleep(1)
os.write(pipeout, 'Number %03d\n' % counter)
counter = (counter+1) % 5
def parent( ):
pipein = open(pipe_name, 'r')
while True:
line = pipein.readline()[:-1]
print 'Parent %d got "%s" at %s' % (os.getpid(), line, time.time( ))
if not os.path.exists(pipe_name):
os.mkfifo(pipe_name)
pid = os.fork()
if pid != 0:
parent()
else:
child()
Why is the example with the threading module hanging?
This does probably not work due to the GIL. The open statement in the thread blocks the whole program. This could be avoided by using multiprocessing module instead.
sure as #hakanc pointed out due to GIL it will block your process. The os.fork is working because it actually spawn an subprocess instead of thread, which is not blocked by GIL.

Python threading global variable issue

I have a few scripts that i want to run simultaneously, they read a CSV file, im trying the following;
import sys
import csv
out = open("C:\PYDUMP\PYDUMPINST.csv","r")
dataf=csv.reader(out)
for row in dataf:
take = row[0]
give = row[1]
def example():
try:
lfo = int(take)
if lfo > 0:
#code
except Exception, e:
pass
example()
This is saved as takefile1.py. I have 20 scripts with similar structures that i want to run simultaneously. So im using(which i have been using for running other batches of scripts trouble free) the following;
import csv
import sys
from threading import Thread
def firstsend_lot():
execfile("C:\Users\takefile1.py")
execfile("C:\Users\takefile2.py")
def secondsend_lot():
execfile("C:\Users\takefile3.py")
execfile("C:\Users\takefile4.py")
if __name__ == '__main__':
Thread(target = firstsend_lot).start()
Thread(target = secondsend_lot).start()
So i am getting the error "global name 'take' is not defined". Anyone got any suggestions? Im pretty hopeless at Python so pretend you are talking to an idiot.
Your function example(), do not have access to take. Try adding a line in it:
def example():
global take
try:
lfo = int(take)
if lfo > 0:
#code
except Exception, e:
pass

Why isn't atexit registering in python?

I have a loop in Tkinter:
def main():
#Global Variables
windows = []
buttons = []
labels = []
messageboxes = []
global theme
theme = 0
listboxes = []
global register
register = []
global path
path = ""
# Lotsa' Code
Tkinter.mainloop()
if __name__ == "__main__":
main()
def save_f():
global register
outFile = open('FobbySave.txt', 'wb')
pickle.dump(register, outFile)
outFile.close()
global register
#At Quit
atexit.register(save_f)
atexit fails. But when I try to print register it has no problem. save_f worked when I put it in the Tkinter loop, but atexit didn't. So can somebody tell me what am I doing wrong?
P.S.
Sorry forgot to write atexit the first time. But it's in my code.
Edit: Orginal code down here
import pickle
import atexit
def save_f():
global register
outFile = open('Something.txt', 'wb')
pickle.dump(register, outFile)
outFile.close()
atexit.register(save_f)
OK turns out the problem was that I needed atexit.register(save_f) instead of atexit.register(save_f()).
You're not supposed to make a function call!
Looking at your code I would suggest to try this instead:
def main():
# ... everything in main ...
Tkinter.mainloop()
def save_f():
outFile = open('FobbySave.txt', 'wb')
pickle.dump(register, outFile)
outFile.close()
#At Quit
atexit.register(save_f)
if __name__ == "__main__":
main()
The problem might have been that you initialize your atexit after you run the main method. So after the code gets killed (and stops executing) you try to add the atexit method.
Your basic script works for me, provided I import atexit and set register to something. e.g.:
import pickle
import atexit
def save_f():
outFile = open('Something.txt', 'wb')
pickle.dump(register, outFile)
outFile.close()
register = 1
atexit.register(save_f)
(note that global isn't necessary either). In cases such as this, you should make sure that you don't have another file named atexit.py in the current directory or somewhere else on your PYTHONPATH ...

Prevent running concurrent instances of a python script [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python: single instance of program
I need to prevent a cron job from running concurrent instances when a job takes longer to complete than the launcher interval. I'm trying to use the flock concept to achieve this, but fcntl module is not behaving the way I expect.
Can anyone tell me why this works to prevent two concurrent instances:
import sys
import time
import fcntl
file_path = '/var/lock/test.py'
file_handle = open(file_path, 'w')
try:
fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
print 'no other instance is running'
for i in range(5):
time.sleep(1)
print i + 1
except IOError:
print 'another instance is running exiting now'
sys.exit(0)
And why this does not work:
import sys
import time
import fcntl
def file_is_locked(file_path):
file_handle = open(file_path, 'w')
try:
fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
return False
except IOError:
return True
file_path = '/var/lock/test.py'
if file_is_locked(file_path):
print 'another instance is running exiting now'
sys.exit(0)
else:
print 'no other instance is running'
for i in range(5):
time.sleep(1)
print i + 1
My humble opinion (although I may be totally wrong) is that file_handle is local to the function (in the second case) and therefore, it gets destroyed once the function is done.
The following code seems to work as expected:
#!/usr/bin/env python
#http://stackoverflow.com/questions/14406562/prevent-running-concurrent-instances-of-a-python-script
import sys
import time
import fcntl
file_handle = None
def file_is_locked(file_path):
global file_handle
file_handle= open(file_path, 'w')
try:
fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
return False
except IOError:
return True
file_path = '/var/lock/test.py'
if file_is_locked(file_path):
print 'another instance is running exiting now'
sys.exit(0)
else:
print 'no other instance is running'
for i in range(5):
time.sleep(1)
print i + 1
Notice that the only thing I did is setting file_handle as global variable (although I copied the whole code to have a working example)
As I mentioned in my commen on #BorrajaX's answer, since it looks like you are POSIX-bound anyway, you could try using a native named semaphore.
You could use the setlock program from D. J. Bernstein's daemontools instead:
http://cr.yp.to/daemontools/setlock.html
Easiest way would be to create a file /tmp/scriptlock at the start of the script and check if that file exists before doing work. Make sure the lock file is removed though at the end of processing.

Categories