Thread is the smallest unit that the operating system can schedule operations. It is included in the process and is the actual operating unit of the process. A thread refers to a single sequential control flow in a process. Multiple threads can be concurrent in a process. Each thread performs different tasks in parallel.
Using the threading module
Method 1:
import threading import time def foo(n): print('foo %s'%n) time.sleep(1) print('end foo') def bar(n): print('bar %s'%n) time.sleep(2) print('end bar') t1 = threading.Thread(target=foo, args=(1,)) t2 = threading.Thread(target=bar, args=(2,)) t1.start() t2.start() print('........in the main..........') //Operation result: foo 1 bar 2 ........in the main.......... end foo end bar
Method two:
import time, threading class MyThread(threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num def run(self): #Define the functions the thread will run print("running on number:%s" % self.num) time.sleep(3) if __name__ == '__main__': t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start() //Operation result: running on number:1 running on number:2
The join method causes the main thread to wait for the child thread to complete before continuing
import threading import time begin = time.time() def foo(n): print('foo %s'%n) time.sleep(1) print('end foo') def bar(n): print('bar %s'%n) time.sleep(2) print('end bar') t1 = threading.Thread(target=foo, args=(1,)) t2 = threading.Thread(target=bar, args=(2,)) t1.start() t2.start() t1.join() t2.join() print('........in the main..........') //Operation result: foo 1 bar 2 end foo end bar ........in the main..........
Serial versus multithreading in compute intensive tasks
import threading, time begin = time.time() def add(n): sum = 0 for i in range(n): sum += i print(sum) add(100000000) add(200000000) end = time.time() print(end-begin) //Operation result: 4999999950000000 19999999900000000 17.66856598854065 import threading, time begin = time.time() def add(n): sum = 0 for i in range(n): sum += i print(sum) t1 = threading.Thread(target=add, args=(100000000,)) t1.start() t2 = threading.Thread(target=add, args=(200000000,)) t2.start() t1.join() t2.join() end = time.time() print(end-begin) //Operation result: 4999999950000000 19999999900000000 21.088160276412964 # The result is that serial runs are faster than multithreading
There is GIL (Global Interpreter Lock) in Cpython, so at the same time, only one thread can enter the schedule. If the task is IO intensive, multithreading can be used; if the task is compute intensive, the optimal method is to change to C.
setDaemon()
Call this method as long as the main thread finishes, no matter whether the sub thread finishes or not, exit together with the main thread.
threading.currentThread()
Returns the current thread variable.
threading.active_count()
Returns the number of running threads.
import threading, time from time import ctime,sleep def music(func): print(threading.current_thread()) for i in range(2): print("Begin listening to %s. %s" %(func, ctime())) sleep(2) print("end listening %s" %ctime()) def movie(func): print(threading.current_thread()) for i in range(2): print("Begin watching at the %s %s" %{func, ctime()}) sleep(4) print("end watching %s" %ctime()) threads = [] t1 = threading.Thread(target=music, args=('klvchen',)) threads.append(t1) t2 = threading.Thread(target=movie, args=('lili',)) threads.append(t2) if __name__ == '__main__': for t in threads: t.setDaemon(True) t.start() print(threading.current_thread()) print(threading.active_count()) print("all over %s" %ctime()) //Operation result: <Thread(Thread-1, started daemon 5856)> Begin listening to klvchen. Wed Jul 11 23:43:51 2018 <Thread(Thread-2, started daemon 9124)> <_MainThread(MainThread, started 9444)> 3 all over Wed Jul 11 23:43:51 2018