multithreading using python - python

Trying to understand the following results when using multithreading with python. The following code prints A and B to the console in random sequence, which is what I would like to achieve. But the second piece of code only prints "A" to the console, and never proceeds past t1.start(). Why is this? What do I need to do the the second section of code to make it behave like the first?
Thanks in advance, this is my first post.
This is the behavior I want :
from threading import Thread
def runA():
while True:
print ('A\n')
def runB():
while True:
print ('B\n')
if __name__ == "__main__":
t1 = Thread(target = runA())
t2 = Thread(target = runB())
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()
while True:
pass
I want the behavior produced from the above code but using classes like in the example below. The code below never executes t2.start(). Why is this?
from threading import Thread
class test():
def runA(self):
while True:
print ('A\n')
def runB(self):
while True:
print ('B\n')
if __name__ == "__main__":
testingNow=test()
t1 = Thread(target = testingNow.runA())
t2 = Thread(target = testingNow.runB())
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()
while True:
pass

Get rid of the () in testingNow.runA() and testingNow.runB().

Related

threading returning DataFrame using queue

Probably a simple question, I'm a beginner.
So, I have a script with a function that returns a DataFrame using threading. Its working fine, but I'm having trouble understanding what's going on when I create the thread. The code:
def test(word,word1):
print(f'start {word}')
df_1 = pd.DataFrame({'test_1':[word],'test_2':[word1]})
time.sleep(2)
print(f'end {word}')
return df_1
my_queue = queue.Queue()
if __name__ == "__main__":
t1_start = perf_counter()
x = threading.Thread(target=lambda q, arg1,arg2: q.put(test(arg1,arg2)), args=(my_queue, 'first','ok1'))
x1 = threading.Thread(target=lambda q, arg1,arg2: q.put(test(arg1,arg2)), args=(my_queue, 'second','ok2'))
x1.start()
x.start()
print('\nrun something')
x.join()
x1.join()
t2_start = perf_counter()
print(f'\n time:{t2_start-t1_start}')
as I said, this script works fine, giving me the following return:
But if I try to remove the lambda function as below:
if __name__ == "__main__":
t1_start = perf_counter()
x = threading.Thread(target=my_queue.put(test('first','ok1')))
x1 = threading.Thread(target=my_queue.put(test('second','ok2')))
x1.start()
x.start()
print('\nrun something')
x.join()
x1.join()
t2_start = perf_counter()
print(f'\n time:{t2_start-t1_start}')
The script will still work, but the threading not. I have the following return:
Why do I need to use a lambda function for threading to work?

Why doesn't my timer thread run in python?

I am making a simple project to learn about threading and this is my code:
import time
import threading
x = 0
def printfunction():
while x == 0:
print("process running")
def timer(delay):
while True:
time.sleep(delay)
break
x = 1
return x
t1 = threading.Thread(target = timer,args=[3])
t2 = threading.Thread(target = printfunction)
t1.start()
t2.start()
t1.join()
t2.join()
It is supposed to just print out process running in the console for three seconds but it never stops printing. The console shows me no errors and I have tried shortening the time to see if I wasn't waiting long enough but it still doesn't work. Then I tried to delete the t1.join()and t2.join()but I still have no luck and the program continues running.
What am I doing wrong?
Add
global x
to the top of timer(). As is, because timer() assigns to x, x is considered to be local to timer(), and its x = 1 has no effect on the module-level variable also named x. The global x remains 0 forever, so the while x == 0: in printfunction() always succeeds. It really has nothing to do with threading :-)

How to start thread from another definition and stop thread from another definition in python?

The current behaviour is that whenever Question endpoint will be from webpage then t1 thread and t2 thread will run but I want the behaviour to be whenever done endpoint is called, both thread should stop
both the definition is different.
how can I do this?
#app.route('/Question')
def Question():
t1 = threading.Thread(target=demoTask,args=())
t2 = threading.Thread(target=demoTask1,args=())
t1.start()
t2.start()
return render_template('questions.html')
#app.route('/done')
def done():
return render_template('done.html')
I found the answer.
we can create thread outside the definition in python.
and we can start from any definition and we can stop from any definition in python.
this is working for me.
t1 = threading.Thread(target=demoTask,args=())
t2 = threading.Thread(target=demoTask1,args=())
t3 = threading.Thread(target=demoTask2,args=())
#app.route('/instructions')
def instructions():
return render_template('instructions.html')
#app.route('/thankyou')
def thankyou():
return render_template('thankyou.html')
#app.route('/Question')
def Question():
t1.start()
t2.start()
return render_template('questions.html')
#app.route('/done')
def done():
t3.start()
return render_template('done.html')

Communicate data between threads in python

I am new to python I have very little knowledge about threads in python. Here is my sample code.
import threading
from threading import Thread
import time
check = False
def func1():
print ("funn1 started")
while check:
print ("got permission")
def func2():
global check
print ("func2 started")
time.sleep(2)
check = True
time.sleep(2)
check = False
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
What I want is to see see "got permission" as the output. But with my current code it is not happening. I assume that the func1 thread is closed before func2 changes the check value to True.
How can I keep func1 alive?
I have researched on the internet but I could not found a solution.
Any help would be appreciated.
Thank you in advance!
The problem here is that func1 performs the check in the while loop, finds it is false, and terminates. So the first thread finishes without printing "got permission".
I don't think this mechanism is quite what you are looking for. I would opt to use a Condition like this,
import threading
from threading import Thread
import time
check = threading.Condition()
def func1():
print ("funn1 started")
check.acquire()
check.wait()
print ("got permission")
print ("funn1 finished")
def func2():
print ("func2 started")
check.acquire()
time.sleep(2)
check.notify()
check.release()
time.sleep(2)
print ("func2 finished")
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
Here the condition variable is using a mutex internally to communicate between the threads; So only one thread can acquire the condition variable at a time. The first function acquires the condition variable and then releases it but registers that it is going to wait until it receives a notification via the condition variable. The second thread can then acquire the condition variable and, when it has done what it needs to do, it notifies the waiting thread that it can continue.
from threading import Thread
import time
check = False
def func1():
print ("funn1 started")
while True:
if check:
print ("got permission")
break
def func2():
global check
print ("func2 started")
time.sleep(2)
check = True
time.sleep(2)
check = False
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
func1 must be like this
def func1():
print("func1 started")
while True:
if check:
print("got permission")
break
else:
time.sleep(0.1)

timing a python program with threads

I have the following block of code that is part of a larger program. I am trying to get it to print the execution time once all of the threads are closed but can't seem to get it to work. Any ideas?
import time
import csv
import threading
import urllib.request
def openSP500file():
SP500 = reader(open(r'C:\Users\test\Desktop\SP500.csv', 'r'), delimiter=',')
for x in SP500:
indStk = x[0]
t1 = StockData(indStk)
t1.start()
if not t1.isAlive():
print(time.clock()-start_time, 'seconds')
else:
pass
def main():
openSP500file()
if __name__ == '__main__':
start_time = time.clock()
main()
Thanks!
You aren't waiting for all the threads to finish (only the last one created). Perhaps something like this in your thread-spawning loop?
threads = []
for x in SP500:
t1 = StockData(x[0])
t1.start()
threads.append(t1)
for t in threads:
t.join()
... print running time

Categories