How can I create multiple threads - python

I am working on python 3 and my class is as below.
class MyClass():
def values(self):
***values***
i =0
def check_values(self):
for i in ValueList[i:i+1]:
self.server_connect()
new_value = self.update.values(i)
def run(self):
self.check_values()
if __name__ == "__main__"
format1 = "%(asctime)s: %(message)s"
logging.basicConfig(format=format1, level=logging.INFO,
datefmt="%H:%M:%S")
for i in range(4):
thread = threading.Thread(target=MyClass().run())
threads.append(thread)
i += 1
print("the %s thread is running", thread)
thread.start()
There are no threads getting created but code works.
I am not able to catch what I am doing wrong here.
EDIT
First, I would like to thank you for response and time given for the answer.
I have to update code and inherit other class as per new update from team as below.
class MyClass(MainServer):
Now, the server has it's own run function as below.
class MainServer(object):
***constructor***
***other functions ***
def run(self):
self.add_arguments()
self.parse_arguments()
self.check_values()
Now, without run(), my code is not properly running.
while including run() as below.
*** main ***
update_perform = MyClass()
for i range(4):
thread = threading.Thread(target=Myclass().run()) <-- code starts from here
threads.append(thread)
i += 1
print("the %s thread is running", thread)
thread.start() <-- not reaching till here
As per my knowledge I will require thread.start() to start threading. So I have tried below option
class MyClass(MainServer):
***code as above***
def check_values(self):
self.server_authenticate()
update_value = self.update.values()
def run(self):
self.server_connect()
i = 0
threads = list()
for i in ValueList[i:i+1]:
print("Updating the value = ", i)
thread = threading.Thread(target=check_values(), args=[i])
thread.start()
i += 1
print("Currently running thread", thread)
threads.append(thread)
for thread in threads:
thread.join()
Here thread is executing from start and in print I can see as below
for threading :-
Currently running threads = <Thread(Thread-8, stopped 14852)>
But for the value I can see only one is in process as below
for value :-
Updating the value = 10 <- first value
So, now threads may be getting created but the values are not getting executed in parallel.
Which I am not able to figure out.

modify the run function like this
def run(self):
self.check_values()

Related

Unexpected output with Lock.acquire() and Lock.release()

from threading import Thread
import threading
import time
def procesa1():
lock = threading.Lock()
lock.acquire()
for i in range(3):
print(threading.get_ident())
lock.release()
if __name__ == "__main__":
hilos = []
for i in range(5):
hilos.append(Thread(target=procesa1))
for thread in hilos:
thread.start()
The 3 print in each thread should come out in a row, shouldn't they?
A thread WINS the lock, prints its 3 outputs in a row (not interspersed with those of the other threads) and then the 3 outputs of the next thread.
This is an example of the multiple random outputs:
13108
13108
13108
12780
12780
12780
7756 // what?
6844
6844
6844
7756 // what?
7756 // what?
11936 //good
11936 //good
11936 //good, they are consecutive
The lock is supposed to be for a critical "atomic" section accessed by one thread AT A TIME.
What am I losing?
The lock doesn't help to synchronize threads because each thread is creating its own lock. You need to create a single lock and pass it as an argument to each thread, so they can share it.
This works as expected (I simplified the syntax using with):
def procesa1(lock):
with lock:
for i in range(3):
print(threading.get_ident())
if __name__ == "__main__":
lock = threading.Lock()
hilos = []
for i in range(5):
hilos.append(Thread(target=procesa1, args=(lock,)))
for thread in hilos:
thread.start()
Output:
34360446720
34360446720
34360446720
34360360224
34360360224
34360360224
[....]

Python: Change class member in a thread

I am currently trying to change member variables of a class via a separate thread. I want to access the changed variables from the main process, but it seems that a copy is always created that is no longer visible to the main thread. Do you have any ideas here?
Many thanks in advance for your help.
Example code:
class foo():
def __init__(self):
self.data = 0
def test_f(self):
for it in range(0,3):
self.data = self.data + 1
time.sleep(1.0)
print('thread terminated')
print(self.data)
#This function is outside the class; Unfortunately, indentations do not work properly here right now
def run(m_foo):
for it in range(0,10):
m_foo.test_f(q)
time.sleep(1.0)
if __name__ == '__main__':
m_foo = foo()
p = Process(target=run, args=(m_foo))
p.start()
stop_char = ""
while stop_char.lower() != "q":
stop_char = input("Enter 'q' to quit\n")
print("Process data:")
print(foo.data)
if p.is_alive():
p.terminate()
Output:
Process data:
0
....
thread terminated
21
thread terminated
24
thread terminated
27
thread terminated
30
...
Process data:
0
The class multiprocessing.Process does not create a thread. It creates a completely new processing with its own memory space.
Use threading.Thread instead:
https://docs.python.org/3/library/threading.html#threading.Thread

twisted - run in a thread

new to python
new to twisted
My team wants me to make some existing code run in a seperate thread.
I've come up with a fictional example:
from twisted.internet import threads, reactor
from twisted.internet.defer import inlineCallbacks
from time import sleep
class SomeClass(object):
def __init__(self):
self.working = False
def set_working(self, is_working):
self.working = is_working
print 'Flag set to {}'.format(is_working)
#inlineCallbacks
def do_worker_thread(self):
# I want to make this call on the main thread
self.set_working(True)
# I want to do all this garbage on a separate thread and keep trucking on the main thread
# This mimics some calls in the real code. There is a call to deferToThread and a try
# except block there.
def thread_proc():
try:
for i in range(0, 100):
print 'Step %d starting'.format(i)
self.execute_step(i)
except Exception:
print 'An exception happened'
reactor.callInThread(thread_proc)
# When the worker thread is done, I want to call back 'on_thread_work_done'
def execute_step(self, num):
sleep(num)
print 'Worker thread: %d'.format(num)
def on_thread_work_done(self):
"""I want to be called back when the worker thread is done"""
self.set_working(False)
#inlineCallbacks
def do_main_thread(self):
for c in range(ord('a'), ord('z')+1):
sleep(c)
print 'Main thread: {}'.format(c)
if __name__ == "__main__":
someClass = SomeClass()
result = someClass.do_worker_thread()
result.addCallback(someClass.do_main_thread())
reactor.run()
The stuff on do_worker_thread currently runs on the main thread. I put a comment in there were I want it to run in a seperate thread. It is important that do_worker_thread returns immediately.
I expect the output to look something like:
Flag set to True
Step 0 starting
Main thread: a
Worker thread: 0
Worker thread: 1
Main thread: b
Worker thread: 2
Main thread: c
...
How can I alter what's in do_worker_thread, such that my set_working calls are on the main thread and it isn't set to False until the worker thread is done its work?
Try giving this a shot. It uses callFromThread() to schedule the work on the main thread.
from twisted.internet import threads, reactor
from twisted.internet.defer import inlineCallbacks, returnValue
from time import sleep
class SomeClass(object):
def __init__(self):
self.working = False
def set_working(self, is_working):
self.working = is_working
print 'Flag set to {}'.format(is_working)
#inlineCallbacks
def do_worker_thread(self):
# I want to make this call on the main thread
self.set_working(True)
# I want to do all this garbage on a separate thread and keep trucking on the main thread
# This mimics some calls in the real code. There is a call to deferToThread and a try
# except block there.
def thread_proc():
try:
for i in xrange(0, 10):
print 'Step {} starting'.format(i)
self.execute_step(i)
except Exception:
print 'An exception happened'
yield threads.deferToThread(thread_proc)
# When the worker thread is done, I want to call back 'on_thread_work_done'
self.on_thread_work_done()
returnValue(17)
def execute_step(self, num):
sleep(1)
print 'Worker thread: {}'.format(num)
def on_thread_work_done(self):
"""I want to be called back when the worker thread is done"""
self.set_working(False)
def do_main_thread(self):
for i in [chr(x) for x in range(ord('a'), ord('z')+1)]:
print 'Main thread: {}'.format(i)
sleep(1)
def thread_done(self, result):
print 'Thread done: {}'.format(result)
if __name__ == "__main__":
someClass = SomeClass()
# Schedule the threaded work
result = someClass.do_worker_thread().addCallback(someClass.thread_done)
# Schedule the main thread work
reactor.callFromThread(someClass.do_main_thread)
reactor.run()
You can use either callFromThread or blockingCallFromThread.

threads not running parallel in python script

I am new to python and threading. I am trying to run multiple threads at a time. Here is my basic code :
import threading
import time
threads = []
print "hello"
class myThread(threading.Thread):
def __init__(self,i):
threading.Thread.__init__(self)
print "i = ",i
for j in range(0,i):
print "j = ",j
time.sleep(5)
for i in range(1,4):
thread = myThread(i)
thread.start()
While 1 thread is waiting for time.sleep(5) i want another thread to start. In short, all the threads should run parallel.
You might have some misunderstandings on how to subclass threading.Thread, first of all __init__() method is roughly what represents a constructor in Python, basically it'll get executed every time you create an instance, so in your case when thread = myThread(i) executes, it'll block till the end of __init__().
Then you should move your activity into run(), so that when start() is called, the thread will start to run. For example:
import threading
import time
threads = []
print "hello"
class myThread(threading.Thread):
def __init__(self, i):
threading.Thread.__init__(self)
self.i = i
def run(self):
print "i = ", self.i
for j in range(0, self.i):
print "j = ",j
time.sleep(5)
for i in range(1,4):
thread = myThread(i)
thread.start()
P.S. Because of the existence of GIL in CPython, you might not be able to fully take advantages of all your processors if the task is CPU-bound.
Here is an example on how you could use threading based on your code:
import threading
import time
threads = []
print "hello"
def doWork(i):
print "i = ",i
for j in range(0,i):
print "j = ",j
time.sleep(5)
for i in range(1,4):
thread = threading.Thread(target=doWork, args=(i,))
threads.append(thread)
thread.start()
# you need to wait for the threads to finish
for thread in threads:
thread.join()
print "Finished"
import threading
import subprocess
def obj_func(simid):
simid = simid
workingdir = './' +str (simid) # the working directory for the simulation
cmd = './run_delwaq.sh' # cmd is a bash commend to launch the external execution
subprocess.Popen(cmd, cwd=workingdir).wait()
def example_subprocess_files():
num_threads = 4
jobs = []
# Launch the threads and give them access to the objective function
for i in range(num_threads):
workertask = threading.Thread(target=obj_func(i))
jobs.append(workertask)
for j in jobs:
j.start()
for j in jobs:
j.join()
print('All the work finished!')
if __name__ == '__main__':
example_subprocess_files()
This one not works for my case that the task is not print but CPU-Intensive task. The thread are excluded in serial.

Python GUI stays frozen waiting for thread code to finish running

I have a python GUI program that needs to do a same task but with several threads. The problem is that I call the threads but they don't execute parallel but sequentially. First one executes, it ends and then second one, etc. I want them to start independently.
The main components are:
1. Menu (view)
2. ProcesStarter (controller)
3. Process (controller)
The Menu is where you click on the "Start" button which calls a function at ProcesStarter.
The ProcesStarter creates objects of Process and threads, and starts all threads in a for-loop.
Menu:
class VotingFrame(BaseFrame):
def create_widgets(self):
self.start_process = tk.Button(root, text="Start Process", command=lambda: self.start_process())
self.start_process.grid(row=3,column=0, sticky=tk.W)
def start_process(self):
procesor = XProcesStarter()
procesor_thread = Thread(target=procesor.start_process())
procesor_thread.start()
ProcesStarter:
class XProcesStarter:
def start_process(self):
print "starting new process..."
# thread count
thread_count = self.get_thread_count()
# initialize Process objects with data, and start threads
for i in range(thread_count):
vote_process = XProcess(self.get_proxy_list(), self.get_url())
t = Thread(target=vote_process.start_process())
t.start()
Process:
class XProcess():
def __init__(self, proxy_list, url, browser_show=False):
# init code
def start_process(self):
# code for process
When I press the GUI button for "Start Process" the gui is locked until both threads finish execution.
The idea is that threads should work in the background and work in parallel.
you call procesor.start_process() immediately when specifying it as the target of the Thread:
#use this
procesor_thread = Thread(target=procesor.start_process)
#not this
procesor_thread = Thread(target=procesor.start_process())
# this is called right away ^
If you call it right away it returns None which is a valid target for Thread (it just does nothing) which is why it happens sequentially, the threads are not doing anything.
One way to use a class as the target of a thread is to use the class as the target, and the arguments to the constructor as args.
from threading import Thread
from time import sleep
from random import randint
class XProcesStarter:
def __init__(self, thread_count):
print ("starting new process...")
self._i = 0
for i in range(thread_count):
t = Thread(
target=XProcess,
args=(self.get_proxy_list(), self.get_url())
)
t.start()
def get_proxy_list(self):
self._i += 1
return "Proxy list #%s" % self._i
def get_url(self):
self._i += 1
return "URL #%d" % self._i
class XProcess():
def __init__(self, proxy_list, url, browser_show=False):
r = 0.001 * randint( 1, 5000)
sleep(r)
print (proxy_list)
print (url)
def main():
t = Thread( target=XProcesStarter, args=(4, ) )
t.start()
if __name__ == '__main__':
main()
This code runs in python2 and python3.
The reason is that the target of a Thread object must be a callable (search for "callable" and "__call__" in python documentation for a complete explanation).
Edit The other way has been explained in other people's answers (see Tadhg McDonald-Jensen).
I think your issue is that in both places you're starting threads, you're actually calling the method you want to pass as the target to the thread. That runs its code in the main thread (and tries to start the new thread on the return value, if any, once its done).
Try:
procesor_thread = Thread(target=procesor.start_process) # no () after start_process
And:
t = Thread(target=vote_process.start_process) # no () here either

Categories