Python: threading multiple infinite loops at the same time - python

In Python I am trying to get one infinite loop to start running parallel at the same time, a simple example would be:
from threading import Thread
def func(argument):
while True:
print(argument)
def main():
Thread(target=func("1")).start()
Thread(target=func("2")).start()
Thread(target=func("3")).start()
Thread(target=func("4")).start()
if __name__ == '__main__':
main()
Right now only the first thread runs, so the result is:
1
1
1
1
....
And it should be:
1
2
3
4
....
I found several similar questions but none of the provided solutions seem to work for me, including using join on the threads.
So if anyone knows the solution to my problem it would be very much appreciated.
Thanks in advance!

The first Thread isn't starting. You are calling the func in main and attempting to set its return value as target, but it runs forever and the first Thread never gets created. You want:
from threading import Thread
def func(argument):
while True:
print(argument)
def main():
Thread(target=func,args=("1",)).start()
Thread(target=func,args=("2",)).start()
Thread(target=func,args=("3",)).start()
Thread(target=func,args=("4",)).start()
if __name__ == '__main__':
main()
This will pass func as an object. Starting the thread will call that object with the tuple of args specified.

You can define your own thread:
from threading import Thread
class MyThread(Thread):
def __init__(self,argument, **kwargs):
super(MyThread, self).__init__(**kwargs)
self.argument = argument
def run(self):
while True:
print self.argument
if __name__ == '__main__':
MyThread('1').start()
MyThread('2').start()
MyThread('3').start()
MyThread('4').start()

Related

How could a function look like, that can add an other function to a list of functions that run parallel in python?

def update():
while True:
loadData()
def main():
doStuff()
addToParallelFunctions(update)
doOtherStuff()
if __name__ == '__main__':
addToParallelFunctions(main)
How could that addToParallelFunctions function look like, so that update runs parallel to main and that I can add other functions to run also parallel to the main?
I've tried that, but it paused the main function and ran the other function until she was finished.
from multiprocessing import Process
def addProcess(*funcs):
for func in funcs:
Process(target=func).start()
I enhanced your example:
It works for me. Main script and function continue both.
import time
from multiprocessing import Process
def addProcess(*funcs):
for func in funcs:
Process(target=func).start()
def update():
for i in range(20):
print(i)
time.sleep(2)
def main():
print("start")
addProcess(update)
print("Main function continues")
if __name__ == '__main__':
addProcess(main)
print("main script continues")
Next time, please post an example that is reproducible.

Threading with Bottle.py Server

I'm having an issue with threading that I can't solve in any way I've tried. I searched in StackOverflow too, but all I could find was cases that didn't apply to me, or explanations that I didn't understand.
I'm trying to build an app with BottlePy, and one of the features I want requires a function to run in background. For this, I'm trying to make it run in a thread. However, when I start the thread, it runs twice.
I've read in some places that it would be possible to check if the function was in the main script or in a module using if __name__ == '__main__':, however I'm not able to do this, since __name__ is always returning the name of the module.
Below is an example of what I'm doing right now.
The main script:
# main.py
from MyClass import *
from bottle import *
arg = something
myObject = Myclass(arg1)
app = Bottle()
app.run('''bottle args''')
The class:
# MyClass.py
import threading
import time
class MyClass:
def check_list(self, theList, arg1):
a_list = something()
time.sleep(5)
self.check_list(a_list, arg1)
def __init__(self, arg1):
if __name__ == '__main__':
self.a_list = arg.returnAList()
t = threading.Thread(target=self.check_list, args=(a_list, arg1))
So what I intend here is to have check_list running in a thread all the time, doing something and waiting some seconds to run again. All this so I can have the list updated, and be able to read it with the main script.
Can you explain to me what I'm doing wrong, why the thread is running twice, and how can I avoid this?
This works fine:
import threading
import time
class MyClass:
def check_list(self, theList, arg1):
keep_going=True
while keep_going:
print("check list")
#do stuff
time.sleep(1)
def __init__(self, arg1):
self.a_list = ["1","2"]
t = threading.Thread(target=self.check_list, args=(self.a_list, arg1))
t.start()
myObject = MyClass("something")
Figured out what was wrong thanks to the user Weeble's comment. When he said 'something is causing your main.py to run twice' I remembered that Bottle has an argument that is called 'reloader'. When set to True, this will make the application load twice, and thus the thread creation is run twice as well.

Need help on tornado coroutines

I'm new to python and tornado. I was trying some stuff with coroutines.
def doStuff(callback):
def task():
callback("One Second Later")
Timer(1,task).start()
#gen.coroutine
def routine1():
ans = yield gen.Task(doStuff)
raise gen.Return(ans)
if __name__ == "__main__":
print routine1()
I'm trying to get the result of doStuff() function, which I expect to be "One Second Later". But it's not working. Any help would be appreciated. Thank you
What's probably happening is, you haven't started the IOLoop, nor are you waiting for your coroutine to complete before your script exits. You'll probably notice your script runs in a couple milliseconds, rather than pausing for a second as it ought. Do this:
if __name__ == "__main__":
from tornado.ioloop import IOLoop
print IOLoop.instance().run_sync(routine1)

Different way to implement this threading?

I'm trying out threads in python. I want a spinning cursor to display while another method runs (for 5-10 mins). I've done out some code but am wondering is this how you would do it? i don't like to use globals, so I assume there is a better way?
c = True
def b():
for j in itertools.cycle('/-\|'):
if (c == True):
sys.stdout.write(j)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
else:
return
def a():
global c
#code does stuff here for 5-10 minutes
#simulate with sleep
time.sleep(2)
c = False
Thread(target = a).start()
Thread(target = b).start()
EDIT:
Another issue now is that when the processing ends the last element of the spinning cursor is still on screen. so something like \ is printed.
You could use events:
http://docs.python.org/2/library/threading.html
I tested this and it works. It also keeps everything in sync. You should avoid changing/reading the same variables in different threads without synchronizing them.
#!/usr/bin/python
from threading import Thread
from threading import Event
import time
import itertools
import sys
def b(event):
for j in itertools.cycle('/-\|'):
if not event.is_set():
sys.stdout.write(j)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
else:
return
def a(event):
#code does stuff here for 5-10 minutes
#simulate with sleep
time.sleep(2)
event.set()
def main():
c = Event()
Thread(target = a, kwargs = {'event': c}).start()
Thread(target = b, kwargs = {'event': c}).start()
if __name__ == "__main__":
main()
Related to 'kwargs', from Python docs (URL in the beginning of the post):
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
...
kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.
You're on the right track mostly, except for the global variable. Normally you'd needed to coordinate access to shared data like that with a lock or semaphore, but in this special case you can take a short-cut and just use whether one of the threads is running or not instead. This is what I mean:
from threading import Thread
from threading import Event
import time
import itertools
import sys
def monitor_thread(watched_thread):
chars = itertools.cycle('/-\|')
while watched_thread.is_alive():
sys.stdout.write(chars.next())
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
def worker_thread():
# code does stuff here - simulated with sleep
time.sleep(2)
if __name__ == "__main__":
watched_thread = Thread(target=worker_thread)
watched_thread.start()
Thread(target=monitor_thread, args=(watched_thread,)).start()
This is not properly synchronized. But I will not try to explain it all to you right now because it's a whole lot of knowledge. Try to read this: http://effbot.org/zone/thread-synchronization.htm
But in your case it's not that bad that things aren't synchronized correctyl. The only thing that could happen, is that the spining bar spins a few ms longer than the background task actually needs.

thread class instance creating a thread function

I have a thread class, in it, I want to create a thread function to do its job corrurently with the thread instance. Is it possible, if yes, how ?
run function of thread class is doing a job at every, excatly, x seconds. I want to create a thread function to do a job parallel with the run function.
class Concurrent(threading.Thread):
def __init__(self,consType, consTemp):
# something
def run(self):
# make foo as a thread
def foo (self):
# something
If not, think about below case, is it possible, how ?
class Concurrent(threading.Thread):
def __init__(self,consType, consTemp):
# something
def run(self):
# make foo as a thread
def foo ():
# something
If it is unclear, please tell . I will try to reedit
Just launch another thread. You already know how to create them and start them, so simply write another sublcass of Thread and start() it along the ones you already have.
Change def foo() for a Thread subclass with run() instead of foo().
First of all, I suggest the you will reconsider using threads. In most cases in Python you should use multiprocessing instead.. That is because Python's GIL.
Unless you are using Jython or IronPython..
If I understood you correctly, just open another thread inside the thread you already opened:
import threading
class FooThread(threading.Thread):
def __init__(self, consType, consTemp):
super(FooThread, self).__init__()
self.consType = consType
self.consTemp = consTemp
def run(self):
print 'FooThread - I just started'
# here will be the implementation of the foo function
class Concurrent(threading.Thread):
def __init__(self, consType, consTemp):
super(Concurrent, self).__init__()
self.consType = consType
self.consTemp = consTemp
def run(self):
print 'Concurrent - I just started'
threadFoo = FooThread('consType', 'consTemp')
threadFoo.start()
# do something every X seconds
if __name__ == '__main__':
thread = Concurrent('consType', 'consTemp')
thread.start()
The output of the program will be:
Concurrent - I just startedFooThread - I just started

Categories

Resources