Advanced Python: multitasking with threads

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()
    

Keywords: Linux Operation & Maintenance Ubuntu

Added by johnthedeveloper on Thu, 03 Mar 2022 11:46:28 +0200