Threading an endless while loop in Python 2 - python

I'm not sure why this does not work. The thread starts as soon as it is defined and seems to not be in an actual thread... Maybe I'm missing something.
import threading
import time
def endless_loop1():
while True:
print('EndlessLoop1:'+str(time.time()))
time.sleep(2)
def endless_loop2():
while True:
print('EndlessLoop2:'+str(time.time()))
time.sleep(1)
print('Here1')
t1 = threading.Thread(name='t1', target=endless_loop1(), daemon=True)
print('Here2')
t2 = threading.Thread(name='t2', target=endless_loop2(), daemon=True)
print('Here3')
t1.start()
print('Here4')
t2.start()
Outputs:
Here1
EndlessLoop1:1446675282.8
EndlessLoop1:1446675284.8
EndlessLoop1:1446675286.81

You need to give target= a callable object.
target=endless_loop1()
Here you're actually calling endless_loop1(), so it gets executed in your main thread right away. What you want to do is:
target=endless_loop1
which passes your Thread the function object so it can call it itself.
Also, daemon isn't actually an init parameter, you need to set it separately before calling start:
t1 = threading.Thread(name='t1', target=endless_loop1)
t1.daemon = True

Related

Python threading event object - How to notify specific thread?

I have multiple threads that uses an event object to wait with a timeout. If I wanted to call set() on the event, this would unblock all of the threads. What would be a good way to unblock a specific thread, and leave the other threads in a waiting state?
I've thought about instead of waiting, each thread would have a while loop using a global variable as a condition to signal when the thread should return, however I'm not sure how this could keep the timeout I want for each thread, without checking for timestamps.
import threading
import time
t1 = threading.Thread(target=startTimeout)
t2 = threading.Thread(target=startTimeout)
timeoutEvent = threading.Event()
time.sleep(0.3)
timeoutEvent.set()
# How to have indivial timeoutEvents for specific threads?
def startTimeout():
check = timeoutEvent.wait(1)
if (check):
# set was called
else:
# Timeout
you can create an event for each thread, or a group of threads, just pass it as argument to them or store it somewhere.
import threading
import time
def startTimeout(event):
check = event.wait(1)
if (check):
print('pass')
else:
print("didn't pass")
timeoutEvent1 = threading.Event()
timeoutEvent2 = threading.Event()
t1 = threading.Thread(target=startTimeout,args=(timeoutEvent1,))
t2 = threading.Thread(target=startTimeout,args=(timeoutEvent2,))
t1.start()
t2.start()
time.sleep(0.3)
timeoutEvent1.set()
t1.join()
t2.join()
pass
didn't pass

os._exit() called on another thread does not exit a program

I just start a new thread:
self.thread = ThreadedFunc()
self.thread.start()
after something happens I want to exit my program so I'm calling os._exit():
os._exit(1)
The program still works. Everything is functional and it just looks like the os._exit() didn't execute.
Is there a different way to exit a whole program from different thread? How to fix this?
EDIT: Added more complete code sample.
self.thread = DownloadThread()
self.thread.data_downloaded.connect(self.on_data_ready)
self.thread.data_progress.connect(self.on_progress_ready)
self.progress_initialized = False
self.thread.start()
class DownloadThread(QtCore.QThread):
# downloading stuff etc.
sleep(1)
subprocess.call(os.getcwd() + "\\another_process.exe")
sleep(2)
os._exit(1)
EDIT 2: SOLVED! There is a quit(), terminate() or exit() function which just stops the thread. It was that easy. Just look at the docs.
Calling os._exit(1) works for me.
You should use the standard lib threading.
I guess you are using multiprocessing, which is a process-based “threading” interface, which uses similar API to threading, but creates child process instead of child thread. so os._exit(1) only exits child process, not affecting the main process
Also you should ensure you have called join() function in the main thread. Otherwise, it is possible that the operating system schedules to run the main thread to the end before starting to do anything in child thread.
sys.exit() does not work because it is the same as raising a SystemExit exception. Raising an exception in thread only exits that thread, rather than the entire process.
Sample code. Tested under ubuntu by python3 thread.py; echo $?.
Return code is 1 as expected
import os
import sys
import time
import threading
# Python Threading Example for Beginners
# First Method
def greet_them(people):
for person in people:
print("Hello Dear " + person + ". How are you?")
os._exit(1)
time.sleep(0.5)
# Second Method
def assign_id(people):
i = 1
for person in people:
print("Hey! {}, your id is {}.".format(person, i))
i += 1
time.sleep(0.5)
people = ['Richard', 'Dinesh', 'Elrich', 'Gilfoyle', 'Gevin']
t = time.time()
#Created the Threads
t1 = threading.Thread(target=greet_them, args=(people,))
t2 = threading.Thread(target=assign_id, args=(people,))
#Started the threads
t1.start()
t2.start()
#Joined the threads
t1.join() # Cannot remove this join() for this example
t2.join()
# Possible to reach here if join() removed
print("I took " + str(time.time() - t))
Credit: Sample code is copied and modified from https://www.simplifiedpython.net/python-threading-example/

Threading an Infinite Loop

def check_incoming_messages_to_client(incoming_chat_messages,uri_str, kill_threads_subscript):
global kill_threads
messaging = Pyro4.Proxy(uri_str)
while(TRUE):
if(messaging.get_connection() == 'yes'):
msg = messaging.read_messages_to_client()
if (msg):
incoming_chat_messages.insert(END, msg)
if(kill_threads[kill_threads_subscript]):
print('break loop')
break
print('start')
t1 = Thread(target=check_incoming_messages_to_client(incoming_chat_messages[length-1],uri_str, kill_threads_subscript))
t1.setDaemon(True)
t1.start()
print('end')
The code above only print start and not end. That means it was stuck in the infinite loop, which must not be because it was threaded. How will I fix it?
Thread(target=check_incoming_messages_to_client(incoming_chat_messages[length-1],uri_str, kill_threads_subscript)) calls your function, then passes the result as the target (except since it never ends, no result ever materializes, and you never even construct the Thread).
You want to pass the function uncalled, and the args separately so the thread calls it when it runs, rather than the main thread running it before the worker thread even launches:
t1 = Thread(target=check_incoming_messages_to_client,
args=(incoming_chat_messages[length-1], uri_str, kill_threads_subscript))

calling a function from a thread and letting the original thread run in the background

I am calling a function from a thread and as soon as the function starts running both the threads stop working until the function has finished executing and after the function execution the program just stops.
class listen(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.playmusicobject = playmusic()
self.objectspeak = speak()
self.apiobject = googleAPI()
def listening(self):
self.r = sr.Recognizer()
threadLock.acquire()
try:
with sr.Microphone() as source:
print("say something")
self.audio = self.r.listen(source)
finally:
threadLock.release()
def checkingaudio(self):
threadLock.acquire()
try:
# a = str(self.r.recognize_google(self.audio))
a = str(self.r.recognize_google(self.audio))
print(a)
if a in greetings:
self.objectspeak.speaking("I am good how are you?")
if a in music:
print("playing music")
self.playmusicobject.play()
if a in stop:
print("stopping")
self.playmusicobject.b()
if a in api:
self.apiobject.distance()
finally:
threadLock.release()
class playmusic:
def play(self):
playsound.playsound("playthisfile")
if __name__ == "__main__":
while 1:
d = listen()
t1 = threading.Thread(target=d.listening)
t1.start()
t2 = threading.Thread(target=d.checkingaudio)
t2.start()
whenever I call the play function in playmusic both the threads supposedly stop and after the play function's execution the program stops. Is there anyway that the function play or for the matter of fact any other function called by the thread running the function CheckingAudio, won't stop the 2 original threads.I tried running the play function as a thread of its own but was unsucessful in doing so, it just gave me an error that said unable to start thread t3, the way was calling the function as a thread was (and this is probably wrong)
if a in music:
print("playing music")
t3 = threading.Thread(target=self.playmusicobject.play)
t3.start()
I tried creating a runplaythread function in playmusic class but still gave me the error cannot start the thread.
Not sure it will fix your problem, but your last thread's target is wrong, you're using self instead of d to call your instance of listen.
This is your code corrected to replace context:
if a in music:
print("playing music")
t3 = threading.Thread(target=d.playmusicobject.play)
t3.start()
NOTE: A comment would probably have been ok, but not enough rep.
EDIT: Reuse of OP's code for context is now explicitly mentioned. (Though that was obvious enough)
EDIT2: Where you are calling your third thread was not clear, but don't seems ok, see comments.

Python parallel threads

Here the code which download 3 files, and do something with it.
But before starting Thread2 it waits until Thread1 will be finished. How make them run together?
Specify some examples with commentary. Thanks
import threading
import urllib.request
def testForThread1():
print('[Thread1]::Started')
resp = urllib.request.urlopen('http://192.168.85.16/SOME_FILE')
data = resp.read()
# Do something with it
return 'ok'
def testForThread2():
print('[Thread2]::Started')
resp = urllib.request.urlopen('http://192.168.85.10/SOME_FILE')
data = resp.read()
# Do something with it
return 'ok'
if __name__ == "__main__":
t1 = threading.Thread(name="Hello1", target=testForThread1())
t1.start()
t2 = threading.Thread(name="Hello2", target=testForThread2())
t2.start()
print(threading.enumerate())
t1.join()
t2.join()
exit(0)
You are executing the target function for the thread in the thread instance creation.
if __name__ == "__main__":
t1 = threading.Thread(name="Hello1", target=testForThread1()) # <<-- here
t1.start()
This is equivalent to:
if __name__ == "__main__":
result = testForThread1() # == 'ok', this is the blocking execution
t1 = threading.Thread(name="Hello1", target=result)
t1.start()
It's Thread.start()'s job to execute that function and store its result somewhere for you to reclaim. As you can see, the previous format was executing the blocking function in the main thread, preventing you from being able to parallelize (e.g. it would have to finish that function execution before getting to the line where it calls the second function).
The proper way to set the thread in a non-blocking fashion would be:
if __name__ == "__main__":
t1 = threading.Thread(name="Hello1", target=testForThread1) # tell thread what the target function is
# notice no function call braces for the function "testForThread1"
t1.start() # tell the thread to execute the target function
For this, we can use threading but it's not efficient since you want to download files. so the total time will be equal to the sum of download time of all files.
If you have good internet speed, then multiprocessing is the best way.
import multiprocessing
def test_function():
for i in range(199999998):
pass
t1 = multiprocessing.Process(target=test_function)
t2 = multiprocessing.Process(target=test_function)
t1.start()
t2.start()
This is the fastest solution. You can check this using following command:
time python3 filename.py
you will get the following output like this:
real 0m6.183s
user 0m12.277s
sys 0m0.009s
here, real = user + sys
user time is the time taken by python file to execute.
but you can see that above formula doesn't satisfy because each function takes approx 6.14. But due to multiprocessing, both take 6.18 seconds and reduced total time by multiprocessing in parallel.
You can get more about it from here.

Categories

Resources