For personal study only
originate mofi Python:https://mofanpy.com/tutorials/python-basic/basic/ Invasion and deletion
Multithreading is an effective way to speed up program computing , Use threading modular
import threading
# Get the number of activated threads
threading.active_count()
>>> 2
# View all thread information
threading.enumerate()
>>> [<_MainThread(MainThread, started 140736011932608)>, <Thread(SockThread, started daemon 123145376751616)>]
# Look at the running threads
threading.current_thread()
# Add thread threading.Thread() Receiving parameters target Represents the task to be completed by this thread , You need to define
def thread_job():
print('This is a thread of %s' % threading.current_thread())
def main():
thread = threading.Thread(target=thread_job,) # Define the thread
thread.start() # Let the thread start working
if __name__ == '__main__':
main()
No addition
join
It all depends on the execution speed of the two threads . Join injoin
Control threads .example :
t1.join()
wait for t1 After the thread ends , It's going down .
# Import thread 、 Standard module for queues
import threading
import time
from queue import Queue
# Define a function called by multiple threads
def job(l, q):
for i in range(len(l)):
l[i] = l[i] ** 2
q.put(l) # Functions called by multiple threads cannot be used return Return value
def multithreading():
q =Queue() #q Store the return value in , Instead of return The return value of
threads = []
data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
for i in range(4): # Define four threads
t = threading.Thread(target=job,args=(data[i],q)) # Thread The first letter should be capitalized , The called job The function has no parentheses , It's just an index , The parameters are in the back
t.start()# Start thread
threads.append(t) # Put each thread append To the thread list
for thread in threads:
thread.join()
results = []
for _ in range(4):
results.append(q.get()) #q.get() From... In order q Take out a value from
print(results)
if __name__=='__main__':
multithreading()
# result
>>> [[1, 4, 9], [9, 16, 25], [16, 16, 16], [25, 25, 25]]
python The multithreading threading Sometimes it's not particularly ideal . The main reason is , Python On the design of , There is a necessary link , Namely Global Interpreter Lock (GIL). This thing makes Python Or can only deal with one thing at a time .
GIL:
Even though Python Fully support multi-threaded programming , But the interpreter's C The language implementation part is not thread safe when executed in full parallel . actually , The interpreter is protected by a global interpreter lock , It ensures that there is only one... At any time Python Threads execute . GIL The biggest problem is Python Multithreaded programs do not take advantage of multicore CPU The advantages of ( For example, a computationally intensive program that uses multiple threads will only work in a single CPU Run above ). Talking about ordinary GIL Before , One thing to emphasize is GIL It will only affect those who rely heavily on CPU The program ( For example, computational ). If most of your programs will only involve I/O, Such as network interaction , Then multithreading is appropriate , Because they spend most of their time waiting . actually , You can safely create thousands of Python Threads , Modern operating systems run so many threads without any pressure .
lock When different threads use the same shared memory , It can ensure that threads do not affect each other , Use lock Approach is to , Before each thread performs an operation to modify the shared memory , perform
lock.acquire()
Lock the shared memory , Ensure that when the current thread executes , Memory will not be accessed by other threads , After performing the operation , Uselock.release()
Open the lock , Ensure that other threads can use the shared memory .
# Unlocked output result
""" job1job2 11 job2 21 job2 31 job2 41 job2 51 job2 61 job2 71 job2 81 job2 91 job2 101 1 job1 102 job1 103 job1 104 job1 105 job1 106 job1 107 job1 108 job1 109 job1 110 """
# Lock code
import threading
def job1():
global A,lock
lock.acquire()
for i in range(10):
A+=1
print('job1',A)
lock.release()
def job2():
global A,lock
lock.acquire()
for i in range(10):
A+=10
print('job2',A)
lock.release()
if __name__== '__main__':
lock=threading.Lock()
A=0
t1=threading.Thread(target=job1)
t2=threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
# Lock results
""" job1 1 job1 2 job1 3 job1 4 job1 5 job1 6 job1 7 job1 8 job1 9 job1 10 job2 20 job2 30 job2 40 job2 50 job2 60 job2 70 job2 80 job2 90 job2 100 job2 110 """