Creating processes that contains infinite loop in python - python

I want to create processes without waiting for other processes finish which they can't because they are in an infinite loop.
import time
from multiprocessing import Process
def child_function(param1, param2):
print(str(param1 * param2))
while True:
print("doing some stuff")
time.sleep(3)
def main_function():
print("Initializing some things.")
for _ in range(10):
Process(target=child_function(3, 5)).start()
if __name__ == '__main__':
main_function()
This code only starts one process and waits for it to finish. How can I do this?
Edit: Comment answer works fine and the answer below also works fine but for creating thread. Thank you everyone.

Try this Python module Threading
import time
import threading
def child_function(param1, param2):
print(str(param1 * param2))
while True:
print("doing some stuff")
time.sleep(3)
def main_function():
print("Initializing some things.")
for _ in range(10):
x = threading.Thread(target=child_function, args=(3,5, ))
x.start()
main_function()
Explanation: as already mentioned in the comments, notice that we are passing the function as opposed to calling it via the thread constructor, Also you can compare Threading vs Multiprocessing and use whichever best suits the project.

Related

Threading Python3

I am trying to use Threading in Python, and struggle to kick off two functions at the same time, then wait for both to finish and load returned data into variables in the main code. How can this be achieved?
import threading
from threading import Thread
func1():
#<do something>
return(x,y,z)
func2():
#<do something>
return(a,b,c)
Thread(target=func1).start()
Thread(target=func2).start()
#<hold until both threads are done, load returned values>
More clarity is definitely required from the question asked. Perhaps you're after something like the below?
import threading
from threading import Thread
def func1():
print("inside func1")
return 5
def func2():
print("inside func2")
return 6
if __name__ == "__main__":
t1 = Thread(target=func1)
t2 = Thread(target=func2)
threads = [t1, t2]
for t in threads:
t.start()
I believe you were missing the start() method to actually launch your threads?

How to end with a thread from the main thread?

I'm looking for this question online but I can not find any way to do it directly I'm trying the following
class Test(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
for i in range(3):
time.sleep(1)
print(i)
def main():
test = Test()
test.start()
del test
time.sleep(5)
print('end')
main()
the only way to stop the thread is from the run method when the code ends but I can not find any way to end the thread.
You can't. All you can do is ask it nicely (by implementing some sort of inter thread communication like a threading.Queue object, then making your thread check it for instructions) and hope for the best.
You can use this simple approach to stop/kill/end a child thread from the parent thread using some variable that is being checked in child thread periodically:
from threading import Thread
from time import time, sleep
class Test:
some_var = True
def __init__(self):
self.t = Thread(target=self.worker)
#self.t.setDaemon(True)
self.t.start()
def worker(self):
while self.some_var is True:
print("%s > I'm running" % str(time()))
test = Test()
sleep(2)
test.some_var = False
print("End!")
Let me know if I didn't understand your question, but I think I've answered your question "How to end with a thread from the main thread?".

How to not wait for function to finish python

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

Basic multiprocessing with infinity loop and queue

import random
import queue as Queue
import _thread as Thread
a = Queue.Queue()
def af():
while True:
a.put(random.randint(0,1000))
def bf():
while True:
if (not a.empty()): print (a.get())
def main():
Thread.start_new_thread(af, ())
Thread.start_new_thread(bf, ())
return
if __name__ == "__main__":
main()
the above code works fine with extreme high CPU usage, i tried to use multiprocessing with no avail. i have tried
def main():
multiprocessing.Process(target=af).run()
multiprocessing.Process(target=bf).run()
and
def main():
manager = multiprocessing.Manager()
a = manager.Queue()
pool = multiprocessing.Pool()
pool.apply_async(af)
pool.apply_async(bf)
both not working, can anyone please help me? thanks a bunch ^_^
def main():
multiprocessing.Process(target=af).run() # will not return
multiprocessing.Process(target=bf).run()
The above code does not work because af does not return; no chance to call bf. You need to separate run call to start/join so that both can run in parallel. (+ to make them share manage.Queue)
To make the second code work, you need to pass a (manager.Queue object) to functions. Otherwise they will use Queue.Queue global object which is not shared between processes; need to modify af, bf to accepts a, and main to pass a.
def af(a):
while True:
a.put(random.randint(0, 1000))
def bf(a):
while True:
print(a.get())
def main():
manager = multiprocessing.Manager()
a = manager.Queue()
pool = multiprocessing.Pool()
proc1 = pool.apply_async(af, [a])
proc2 = pool.apply_async(bf, [a])
# Wait until process ends. Uncomment following line if there's no waiting code.
# proc1.get()
# proc2.get()
In the first alternative main you use Process, but the method you should call to start the activity is not run(), as one would think, but rather start(). You will want to follow that up with appropriate join() statements. Following the information in multiprocessing (available here: https://docs.python.org/2/library/multiprocessing.html), here is a working sample:
import random
from multiprocessing import Process, Queue
def af(q):
while True:
q.put(random.randint(0,1000))
def bf(q):
while True:
if not q.empty():
print (q.get())
def main():
a = Queue()
p = Process(target=af, args=(a,))
c = Process(target=bf, args=(a,))
p.start()
c.start()
p.join()
c.join()
if __name__ == "__main__":
main()
To add to the accepted answer, in the original code:
while True:
if not q.empty():
print (q.get())
q.empty() is being called every time which is unnecessary since q.get() if the queue is empty will wait until something is available here documentation.
Similar answer here
I assume that this could affect the performance since calling the .empty() every iteration should consume more resources (it should be more noticeable if Thread was used instead of Process because Python Global Interpreter Lock (GIL))
I know it's an old question but hope it helps!

Python time.sleep() does not work in linux and multi thread

I write a simple multiprocess and multi-thread code in python which works in windows but doesn't work in linux (i tested it on freebsd and ubuntu)
import threading
import time
from multiprocessing import Process
class Test(threading.Thread):
def run(self):
print('before sleep')
time.sleep(1)
print('after sleep')
def run_test():
Test().start()
if __name__ == "__main__":
Process(target=run_test, args=()).start()
this program only print "before sleep" and then exit.
why sleep doesn't work here? (it works on windows)
UPDATE:
I used join() in my process like this, but still not work.
...
if __name__ == "__main__":
pr = Process(target=run_test, args=())
pr.start()
pr.join()
The join() should be used in the calling thread to wait for another thread:
def run_test():
t = Test()
t.start()
t.join()

Categories