I have two scripts, new.py and test.py.
Test.py
import time
while True:
x = "hello"
time.sleep(1)
x = "world"
time.sleep(1)
new.py
import time
while True:
import test
x = test.x
print(x)
time.sleep(1)
Now from my understanding this should print "hello" and a second later "world" all the time when executing new.py.
It does not print anything, how can i fix that?
Thanks
I think the code below captures what you are asking. Here I simulate two scripts running independently (by using threads), then show how you can use shelve to communicate between them. Note, there are likely much better ways to get to what you are after -- but if you absolutely must run the scripts independently, this will work for you.
Incidentally, any persistent source would do (such as a database).
import shelve
import time
import threading
def script1():
while True:
with shelve.open('my_store') as holder3:
if holder3['flag'] is not None: break
print('waiting')
time.sleep(1)
print("Done")
def script2():
print("writing")
with shelve.open('my_store') as holder2:
holder2['flag'] = 1
if __name__ == "__main__":
with shelve.open('my_store') as holder1:
holder1['flag'] = None
t = threading.Thread(target=script1)
t.start()
time.sleep(5)
script2()
t.join()
Yields:
waiting
waiting
waiting
waiting
waiting
writing
Done
Test.py
import time
def hello():
callList = ['hello', 'world']
for item in callList:
print item
time.sleep(1)
hello()
new.py
from parent import hello
while True:
hello()
Related
So I have this small program (using Linux):
import getch
while True:
print("Hello World!")
key = getch.getch()
if key == 'q':
break
So all it does is wait for the user to hit a key, and they displays "Hello World!" to the console. However, is there a way so that I can continuously display "Hello World!" to the console, and the only way to get it to end is if the user presses the "q" key?
This question is similar to this one, but it's in C++.
My first thought was to look up threading, however, I tried all the threads I could find and none of them worked. Then I came across the Global Interpreter Lock (GIL), and it supposedly prevents "multiple native threads from executing Python bytecodes at once."
Then I tried to use multiprocessing, but it still didn't work for me. This is how far I got using it:
import multiprocessing
import getch
def test1():
print("Hello World!")
def test2():
key = getch.getch()
if key == 'q':
exit()
while True:
p1 = multiprocessing.Process(target=test1, args=())
p2 = multiprocessing.Process(target=test2, args=())
p1.start()
p2.start()
p1.join()
p2.join()
Am I missing something here? Or is there another way in which I can do something while also waiting for getch()? Or do I have to write this in another language that supports multithreading like C++?
Thanks
I was not able to install fetch, probably because I am on Windows at the moment, but you can implement what you want (However, is there a way so that I can continuously display "Hello World!" to the console, and the only way to get it to end is if the user presses the "q" key?) the following way:
import time
from threading import Thread
def another_thread():
while True:
time.sleep(2)
print("Working...\n")
def main_thread():
while True:
x = input("Press a key: \n")
if x == "q":
break
if __name__ == '__main__':
# create another Thread object
# daemon means that it will stop if the Main Thread stops
th = Thread(target=another_thread, daemon=True)
th.start() # start the side Thread
main_thread() # start main logic
I'm trying to implement very simple multiprocessing code in python 2.7, but it looks like the code run serially and not parallel.
The following code prints *****1***** while I expect it to print *****2***** immediately after *****1*****.
import os
import multiprocessing
from time import sleep
def main():
func1_proc = multiprocessing.Process(target=func1())
func2_proc = multiprocessing.Process(target=func2())
func1_proc.start()
func2_proc.start()
pass
def func1():
print "*****1*****"
sleep(100)
def func2():
print "*****2*****"
sleep(100)
if __name__ == "__main__":
main()
You're calling func1 and func2 before passing their returning values to Process, so func1 is going to sleep 100 seconds before returning None, for which Process will raise an error.
You should pass function objects to Process instead so that it will run them in separate processes:
func1_proc = multiprocessing.Process(target=func1)
func2_proc = multiprocessing.Process(target=func2)
I'm trying to program a loop with a asynchronous part in it. I dont want to wait for this asynchronous part every iteration though. Is there a way to not wait for this function inside the loop to finish?
In code (example):
import time
def test():
global a
time.sleep(1)
a += 1
test()
global a
a = 10
test()
while(1):
print a
You can put it in a thread. Instead of test()
from threading import Thread
Thread(target=test).start()
print("this will be printed immediately")
To expand on blue_note, let's say you have a function with arguments:
def test(b):
global a
time.sleep(1)
a += 1 + b
You need to pass in your args like this:
from threading import Thread
b = 1
Thread(target=test, args=(b, )).start()
print("this will be printed immediately")
Note args must be a tuple.
A simple way is to run test() in another thread
import threading
th = threading.Thread(target=test)
th.start()
You should look at a library meant for asynchronous requests, such as gevent
Examples here: http://sdiehl.github.io/gevent-tutorial/#synchronous-asynchronous-execution
import gevent
def foo():
print('Running in foo')
gevent.sleep(0)
print('Explicit context switch to foo again')
def bar():
print('Explicit context to bar')
gevent.sleep(0)
print('Implicit context switch back to bar')
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
use thread. it creates a new thread in that the asynchronous function runs
https://www.tutorialspoint.com/python/python_multithreading.htm
I have yet another question about Python multiprocessing.
I have a module that creates a Process and just runs in a while True loop.
This module is meant to be enabled/disabled from another Python module.
That other module will import the first one once and is also run as a process.
How would I better implement this?
so for a reference:
#foo.py
def foo():
while True:
if enabled:
#do something
p = Process(target=foo)
p.start()
and imagine second module to be something like that:
#bar.py
import foo, time
def bar():
while True:
foo.enable()
time.sleep(10)
foo.disable()
Process(target=bar).start()
Constantly running a process checking for condition inside a loop seems like a waste, but I would gladly accept the solution that just lets me set the enabled value from outside.
Ideally I would prefer to be able to terminate and restart the process, again from outside of this module.
From my understanding, I would use a Queue to pass commands to the Process. If it is indeed just that, can someone show me how to set it up in a way that I can add something to the queue from a different module.
Can this even be easily done with Python or is it time to abandon hope and switch to something like C or Java
I purposed in comment two different approches :
using a shared variable from multiprocessing.Value
pause / resume the process with signals
Control by sharing a variable
def target_process_1(run_statement):
while True:
if run_statement.value:
print "I'm running !"
time.sleep(1)
def target_process_2(run_statement):
time.sleep(3)
print "Stoping"
run_statement.value = False
time.sleep(3)
print "Resuming"
run_statement.value = True
if __name__ == "__main__":
run_statement = Value("i", 1)
process_1 = Process(target=target_process_1, args=(run_statement,))
process_2 = Process(target=target_process_2, args=(run_statement,))
process_1.start()
process_2.start()
time.sleep(8)
process_1.terminate()
process_2.terminate()
Control by sending a signal
from multiprocessing import Process
import time
import os, signal
def target_process_1():
while True:
print "Running !"
time.sleep(1)
def target_process_2(target_pid):
time.sleep(3)
os.kill(target_pid, signal.SIGSTOP)
time.sleep(3)
os.kill(target_pid, signal.SIGCONT)
if __name__ == "__main__":
process_1 = Process(target=target_process_1)
process_1.start()
process_2 = Process(target=target_process_2, args=(process_1.pid,))
process_2.start()
time.sleep(8)
process_1.terminate()
process_2.terminate()
Side note: if possible do not run a while True.
EDIT: if you want to manage your process in two different files, supposing you want to use a control by sharing a variable, this is a way to do.
# file foo.py
from multiprocessing import Value, Process
import time
__all__ = ['start', 'stop', 'pause', 'resume']
_statement = None
_process = None
def _target(run_statement):
""" Target of the foo's process """
while True:
if run_statement.value:
print "I'm running !"
time.sleep(1)
def start():
global _process, _statement
_statement = Value("i", 1)
_process = Process(target=_target, args=(_statement,))
_process.start()
def stop():
global _process, _statement
_process.terminate()
_statement, _process = None, _process
def enable():
_statement.value = True
def disable():
_statement.value = False
I want to create a python script that prints out messages from one thread, while still waiting for you to input on another. Is this possible? And if so, how?
System: Windows 7
Language: Python 2.7
I have tried this (modified from a different question):
import threading
import time
def message_loop():
while True:
time.sleep(1)
print "Hello World"
thread = threading.Thread(target = message_loop)
thread.start()
while True:
input = raw_input("Prompt> ")
But what happens is: the program waits until I have finished inputting before it outputs Hello World.
It's absolutely possible. If you have a function that prints output (let's call it print_output) you can start it up in a different thread using the threading module:
>>> import threading
>>> my_thread = threading.Thread(target=print_output)
>>> my_thread.start()
You should now start getting your output. You can then run the input bit on the main thread. You could also run it in a new thread, but there are some advantages to running input in the main thread.
This works for me.
The code prints message before you input 'q'
import threading
import time
def run_thread():
while True:
print('thread running')
time.sleep(2)
global stop_threads
if stop_threads:
break
stop_threads = False
t1 = threading.Thread(target=run_thread)
t1.start()
time.sleep(0.5)
q = ''
while q != 'q':
q = input()
stop_threads = True
t1.join()
print('finish')