Python multithreading from multiple files - python-3.x

This is a sample demo of how I want to use threading.
import threading
import time
def run():
print("started")
time.sleep(5)
print("ended")
thread = threading.Thread(target=run)
thread.start()
for i in range(4):
print("middle")
time.sleep(1)
How can I make this threading work demo even from multiple files?
Example:
# Main.py
import background
""" Here I will have a main program and \
I want the command from the background file to constantly run. \
Not just once at the start of the program """
The second file:
# background.py
while True:
print("This text should always be printing \
even when my code in the main function is running")

Put all the lines before your for loop in background.py. When it is imported it will start the thread running. Change the run method to do your infinite while loop.
You may also want to set daemon=True when starting the thread so it will exit when the main program exits.
main.py
import time
import background
for i in range(4):
print("middle")
time.sleep(1)
background.py
import threading
import time
def run():
while True:
print("background")
time.sleep(.5)
thread = threading.Thread(target=run,daemon=True)
thread.start()
Output
background
middle
background
middle
background
background
background
middle
background
background
middle
background
background

Related

Python start multiprocessing without print/logging statements from processes

I am starting two processes via multiprocessing and this is working fine. The only problems which I have are the print and debug statements from these two processes.
The hope is, to use the REPL and start the processes, like in the background. However, I do not get this to run. I always get the debug statements and therefore can't use the REPL anymore. This is how I call the processes:
processes = [
Process(target=start_viewer, args=()),
Process(target=start_server, args=(live, amount, fg))
]
for p in processes:
p.start()
Any idea on how to "mute" the process, or get them in the background?
If I correct understand you, you want to not show printing from one of processes.
You can achieve this by redirect output of the Python Interpreter.
Add sys.stdout = open("/dev/null", 'w') to the process which you want to "mute".
Full working example below.
from multiprocessing import Process
from time import sleep
import sys
def start_viewer():
sys.stdout = open("/dev/null", 'w')
while True:
print("start_viewer")
sleep(1)
def start_server():
while True:
print("start_server")
sleep(1)
if __name__ == '__main__':
processes = [
Process(target=start_viewer, args=()),
Process(target=start_server, args=())
]
for p in processes:
p.start()
Be aware that /dev/null is like passing prints to nowhere, if you want to save it you can use text file. Also to achieve multi os support you should use os.devnull.

how to run and exit python scripts from another python program?

I wish to launch a python file when I send an on request and kill that python process once I send the off request . I am able to send the on and off requests but am not able to run the other python file or kill it from the program I have written.
I could make a subprocess call but I think there should be a way to call other python scripts inside a python script and also a way to kill those scripts once their purpose is fulfilled.
I suggest to use a thread.
Write all the code in your python script in a function doit (except import statements)
and then import it:
content of thescript.py:
import time
def doit(athread):
while not athread.stopped():
print("Hello World")
time.sleep(1)
your program should look like:
import threading
import time
import thescript
class FuncThread(threading.Thread):
def __init__(self, target):
self.target=target
super(FuncThread,self).__init__()
self._stop_event=threading.Event()
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
def run(self):
self.target(self)
t1=FuncThread(thescript.doit)
t1.start()
time.sleep(5)
t1.stop()
t1.join()
You can exit the thread any time, I just waited 5 seconds and then called the stop() method.

ValueError: signal only works in main thread in Flask using threading

I use flask, tkinter and threading modules.
I need to run a tkinter process and a flask process to run at the same time and I want to use threading for that.
So I run
t1 = t.Thread(target=lambda: root.wait_window(root))
t1.start()
to start the tkinter part, and then
if __name__ == '__main__':
app.run(host="0.0.0.0", port=25000, debug=True)
to start the flask part. But it keeps returning "ValueError: signal only works in main thread" when I run the flask part. I tried putting the flask part into the thread and the tkinter part into the main program, but it returns the same error.
How can I fix it?

Python: Kill the parent process after creating child processes

I have a polling job written in Python that is executed every 15 minutes to check if the status of an entry in the job table is True. If the status is true then I need to take the values from the table and pass them as arguments to another script that executes something.
I am creating the child processes using Process in Python's Multiprocessing module but I am unable to exit the polling job(parent script) after starting these processes. The polling job keeps waiting until the children complete even if there is a sys.exit() written after creating the children.
#pollingjob.py
import sys
import multiprocessing
from multiprocessing import Process
from secondscript import secondscriptfunction
def createParallelBatches(a,b,c):
for i in [1,2,3]:
p1 = Process(target=secondscriptfunction,args=(a,b,c)).start()
sys.exit()
if __name__=='__main__':
# Check the table for *status=True* rows
# If such rows exit call CreateParallelBatches with the column values
What I am failing to understand is that, why sys.exit() won't let me exit the program leaving the spawned processes as orphans. I tried subprocess module but it also behaves in the same way. I don't want the parent process waiting on its children to complete. Any help would be appreciated. Thanks.
you need to launch an independent sub process externally. This is one way to do it :
put the secondscriptfunction into one executable python file
File runscript.py
import sys
from secondscript import secondscriptfunction
if __name__=='__main__':
secondscriptfunction(sys.argv[1:]) #passing arguments to the func
use subprocess.popen in your script:
File pollingjob.py
import subprocess
import shlex
def createParallelBatches(a,b,c):
for i in [1,2,3]:
command = "python runscript.py %s %s %s "%(a,b,c)
cmd_args = shlex.split(command)
subprocess.Popen(cmd_args)
sys.exit()
Just remove the process object from the _children set of the current process object, the the parent process will exit immediately.
Theh multiprocessing module manages child processes in a private set and join them when the current process exits. You can remove children from the set if you don't care of them.
process = multiprocessing.Process(target=proc_main)
multiprocessing.current_process()._children.discard(process)
exit(0)

Why do I get NSAutoreleasePool double release when using Python/Pyglet on OS X

I'm using Python 3.5 and Pyglet 1.2.4 on OS X 10.11.5. I am very new to this setup.
I am trying to see if I can use event handling to capture keystrokes (without echoing them to the screen) and return them to the main program one at a time by separate invocations of the pyglet.app.run method. In other words I am trying to use Piglet event handling as if it were a callable function for this purpose.
Below is my test program. It sets up the Pyglet event mechanism and then calls it four times. It works as desired but causes the system messages shown below.
import pyglet
from pyglet.window import key
event_loop = pyglet.app.EventLoop()
window = pyglet.window.Window(width=400, height=300, caption="TestWindow")
#window.event
def on_draw():
window.clear()
#window.event
def on_key_press(symbol, modifiers):
global key_pressed
if symbol == key.A:
key_pressed = "a"
else:
key_pressed = 'unknown'
pyglet.app.exit()
# Main Program
pyglet.app.run()
print(key_pressed)
pyglet.app.run()
print(key_pressed)
pyglet.app.run()
print(key_pressed)
pyglet.app.run()
print(key_pressed)
print("Quitting NOW!")
Here is the output with blank lines inserted for readability. The first message is different and appears even if I comment out the four calls to piglet.app.run. The double release messages do not occur after every call to event handling and do not appear in a consistent manner from one test run to the next.
/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 "/Users/home/PycharmProjects/Test Event Handling/.idea/Test Event Handling 03B.py"
2016-07-28 16:49:59.401 Python[11419:4185158]ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/8q/bhzsqtz900s742c17gkj_y740000gr/T/org.python.python.savedState
a
2016-07-28 16:50:02.841 Python[11419:4185158] *** -[NSAutoreleasePool drain]: This pool has already been drained, do not release it (double release).
2016-07-28 16:50:03.848 Python[11419:4185158] *** -[NSAutoreleasePool drain]: This pool has already been drained, do not release it (double release).
a
a
2016-07-28 16:50:04.632 Python[11419:4185158] *** -[NSAutoreleasePool drain]: This pool has already been drained, do not release it (double release).
a
Quitting NOW!
Process finished with exit code 0
Basic question: Why is this happening and what can I do about it?
Alternate question: Is there a better way to detect and get a users keystrokes without echoing them to the screen. I will be using Python and Pyglet for graphics so I was trying this using Pyglet's event handling.
Try to play with this simple example. It uses the built-in pyglet event handler to send the key pressed to a function that can then handle it. It shows that pyglet.app itself is the loop. You don't need to create any other.
#!/usr/bin/env python
import pyglet
class Win(pyglet.window.Window):
def __init__(self):
super(Win, self).__init__()
def on_draw(self):
self.clear()
# display your output here....
def on_key_press(self, symbol, modifiers):
if symbol== pyglet.window.key.ESCAPE:
exit(0)
else:
self.do_something(symbol)
# etc....
def do_something(symbol):
print symbol
# here you can test the input and then redraw
window = Win()
pyglet.app.run()

Resources