1, Introduction to multitasking
- Multitasking: multiple tasks are executed at the same time, which is multitasking
- python programs are single task by default
2, [key] thread - basic use
-
Thread is the basic unit of CPU scheduling
-
Main thread: after the program starts, there is a default main thread, which is usually called the main thread
Function: 1) create sub threads 2) close other sub threads after execution
-
Subthread: a branch of a program
-
Child thread creation
- Importing module threading
- Create thread object threading Thread (target = name of branch function executed)
- Start the child thread object start()
3, [key] thread - thread name and total number
-
Get the number of threads: the number of active threads
threading.enumerate() - list of currently active thread objects
Length: len (threading.enumerate())
-
Gets the name of the thread
threading.current_thread() gets the current thread object, which contains the name
4, [key] thread - parameters and sequence
-
Thread parameters
-
Tuple args
threading.Tread(target=xxx, args = (parameter 1, parameter 2,...))
The order of the elements in the tuple is consistent with the order of the parameters of the function
-
Dictionary kwargs
# 2. Using a dictionary to pass threading Thread (target = XXX, kwargs = {"parameter name": parameter value,...})
-
Mixed tuples and dictionaries
# 3. Mix tuples and dictionary threading Thread (target = XXX, args = (parameter 1, parameter 2,...), kwargs = {"parameter name": parameter value,...}) thread_sing = threading.Thread(target=sing, args=(10, ), kwargs={"c": 1000, "b": 10})
-
-
Thread order: the execution order of threads is out of order (threads are scheduled by the CPU, and the CPU will schedule the execution according to its own scheduling algorithm according to the running state of the system)
5, [key] thread - daemon thread
-
Thread guard: a convention between the sub thread and the main thread (when the main thread ends, the sub thread also ends)
Child thread setDaemon(True)
6, Parallelism and concurrency
- Concurrency: the number of tasks is greater than the number of CPU cores, which is called concurrent execution
- Parallel: the number of tasks is less than or equal to the number of CPU cores, which is parallel
7, [key and difficult points] custom thread class
-
To customize a thread class
-
Import module
-
Create a class and inherit threading Thread
class MyThread(threading.Thread):
-
Override the run method of the parent class
def run(self):
...
-
Create an object and call start()
mythread = MyThread()
mythread.start()
-
-
Underlying principle
Thread class
- run method
- start()
- The run method is called in start().
-
init method of custom thread class
The subclass first calls the initialization method of the parent class through super, and then initializes the subclass
def __init__(self,num): # First call the init method of the parent class super().__init__() self.num = num
8, [key] multithreading - sharing global variables
- Global variables can be shared between multiple threads
9, [difficulty] multithreading - sharing global variables - problem
-
Existing problems: multiple threads access the same resource at the same time, resulting in resource competition
-
Solution: let a thread execute first
Thread object join()
Disadvantages: turn multithreading into single thread, affecting the overall performance
10, Synchronization
-
Synchronization: in multitasking, multiple tasks are executed in sequence. After one task is executed, the other will be executed again
-
Asynchronous: in multitasking, multiple tasks are executed at the same time without sequence
-
Thread locking mechanism: when a thread obtains a resource, it locks it immediately and unlocks it after the resource is used, effectively ensuring that only
The thread is using resources
11, [key] mutex (key)
-
There are three steps to use mutex:
-
Create a lock
lock1 = threading.Lock()
-
Lock
lock1.acquire()
-
Unlock
lock1.release()
-
-
Principle of using mutex: Lock competing resources as few as possible
12, Deadlock
- Deadlock: in multithreading, two threads occupy some resources and are waiting for each other to release resources at the same time. This state is a deadlock state
- Avoid: release the lock in time after use
Case: multi tasking udp chat (I)
-
Create a sub thread to receive information separately
# Create a sub thread to receive the information sent by the user separately thread_recvmsg = threading.Thread(target=recv_msg, args=(udp_socket, )) # Start child thread thread_recvmsg.start()
-
Delete the menu and judgment of received information
-
Can receive multiple messages
def recv_msg(udp_socket): """Function to receive information""" while True: # 1) Receive data using socket # (b'\xe4\xbc\x91\xe6\x81\xaf\xe4\xbc\x91\xe6\x81\xaf\xe6\x89\x80', ('192.168.150.93', 8080)) recv_data, ip_port = udp_socket.recvfrom(1024) # 2) Decode data recv_text = recv_data.decode() # 3) Output display print("Received[%s]Message:%s" % (str(ip_port), recv_text))
Case: multi task udp chat (2)
-
Let the child thread guard the main thread
# Set the child thread to guard the main thread thread_recvmsg.setDaemon(True)
13, [key] TCP server framework
-
tcp server
1. Import module
2. Create socket
3. Setting addresses can be reused
4. Binding port
5. Set listening, socket active set to passive
6. Accept client connections
7. Receive information sent by the client
8. Decode data and output
9. Close the connection with the current client -
Support multithreading, idea: every time a new client comes, I create a new thread
while True: # 6. Accept client connections new_client_socket, ip_port = tcp_server_socket.accept() print("New users online:",ip_port) # recv_msg(new_client_socket,ip_port) # Create thread thread_recvmsg = threading.Thread(target=recv_msg, args=(new_client_socket, ip_port)) # Set thread daemon thread_recvmsg.setDaemon(True) # Start thread thread_recvmsg.start()