相关推荐recommended
人生苦短,我用Python 九:Flask接口并发处理:多进程、多线程
作者:mmseoamin日期:2023-12-05

文章目录

  • 开发环境
  • 一、任务需求
  • 简单介绍
    • 1. 进程
    • 2. 线程
    • 二、多线程处理7个子任务
    • 三、并发处理10个进程任务
    • 四、综合处理多进程、多线程(任务需求)

      开发环境

      Windows

      一、任务需求

      我现在有一个flask接口文件,我有个需求:,

      让这个接口可以并发处理10个请求任务,每个任务中有7个子线程任务,这7个子线程任务,为的是加快,每个请求任务的处理速度。

      简单介绍

      1. 进程

      进程是操作系统中的一个基本概念,用于描述正在运行的程序。简单来说,进程是计算机中正在进行中的一个任务或程序的实例。可以把进程类比为在电脑上同时运行的多个应用程序。每个应用程序都可以看作是一个独立的进程,它们在操作系统内部占用资源(如CPU、内存等),并通过调度算法由处理器进行切换,以实现并发执行。

      进程的应用场景非常广泛,包括但不限于:

      1. 多任务处理:操作系统可以同时运行多个进程,每个进程处理不同的任务,提高了计算机的效率。
      2. 并发编程:在编写程序时,可以利用多进程来实现并发执行,提高程序的响应能力和处理能力。
      3. 分布式计算:在分布式系统中,可以将一个大型计算任务划分成多个子任务,分配给不同的进程来并行处理。
      4. 服务器应用:对于需要处理大量并发请求的服务端应用,使用多进程可以提供更好的性能和可伸缩性。

        以下是一个示例代码,展示了如何使用Python的multiprocessing库创建并启动一个进程:

      import multiprocessing
      def my_process():
          # 这里是进程需要执行的逻辑
          pass
      if __name__ == '__main__':
          process = multiprocessing.Process(target=my_process)
          process.start()
          process.join()
      

      在这个示例中,我们通过multiprocessing.Process创建了一个进程,并将其目标函数设置为my_process。然后使用start()方法启动进程,并使用join()方法等待进程执行完毕。

      需要注意的是,每个进程都有自己独立的内存空间和系统资源,进程间的通信需要借助特定的机制(如共享内存、管道等)。此外,在使用多进程时还需注意以下事项:

      1. 进程的创建和销毁涉及系统开销,因此过多的进程可能会影响系统性能。
      2. 不同进程之间的数据和状态无法直接共享,需要通过进程间通信(IPC)方式进行数据交换。
      3. 多进程编程需要考虑进程间的同步与互斥,以避免竞态条件和资源冲突。
      4. 在某些操作系统上,每个进程都有一定的资源限制,如虚拟内存、文件描述符等,需要注意合理分配和利用。
      5. 进程是操作系统中的基本概念,用于描述并发运行的程序实例,可以提供更好的任务隔离性、资源管理和并发处理能力。

      2. 线程

      线程是操作系统中的另一个基本概念,用于描述进程内部的执行流。简单来说,线程是进程中独立执行的一段指令序列。

      通俗来讲,可以把线程类比为在应用程序内同时执行的多个子任务。每个子任务都可以看作是一个独立的线程,它们共享相同的内存空间和资源,在进程内部并发执行。

      线程的应用场景包括但不限于以下几个方面:

      1. 并发编程:线程可实现并发处理,提高程序的响应能力和处理能力。特别适用于需要同时处理多个任务且任务之间没有强依赖关系的场景。
      2. 资源共享:由于线程共享进程的地址空间和资源,因此可以方便地进行数据共享和协同处理,提高程序的效率。
      3. 用户界面交互:在GUI应用程序中,可以使用主线程处理用户界面的渲染和事件响应,而使用其他线程执行耗时任务,避免界面卡顿。
      4. 多媒体处理:对于需要实时处理音视频数据的应用,可以使用线程来并发执行解码、编码、渲染等任务。

        下面是一个示例代码,展示了如何使用Python的threading库创建并启动一个线程:

      import threading
      def my_thread():
          # 这里是线程需要执行的逻辑
          pass
      if __name__ == '__main__':
          thread = threading.Thread(target=my_thread)
          thread.start()
          thread.join()
      

      在这个示例中,我们通过threading.Thread创建了一个线程,并将其目标函数设置为my_thread。然后使用start()方法启动线程,并使用join()方法等待线程执行完毕。

      需要注意的是,线程是在进程内部共享资源的并发执行单位,因此需要特别关注以下事项:

      1. 线程间共享数据需要进行同步和互斥操作,以避免竞态条件和数据一致性问题。
      2. 在多线程编程中,需要注意线程安全性,尽量避免使用共享状态和全局变量,或者采用线程安全的数据结构和同步机制。
      3. 线程的创建和销毁开销较小,但过多的线程可能会导致资源浪费和线程调度开销增加。
      4. 由于线程共享进程的资源,因此一个线程的错误可能会影响到其他线程和整个进程的稳定性。
      5. 线程是进程内部独立执行的指令序列,可以提供更好的并发处理能力和资源共享。合理地利用线程可以提高程序的效率和响应能力,但也需要注意线程间的同步和互斥,以及线程安全性的问题。

      二、多线程处理7个子任务

      使用Python中的threading库来并发处理子线程任务

      from flask import Flask
      import threading
      app = Flask(__name__)
      def process_sub_task():
          # 这里是每个子线程任务需要执行的逻辑
          pass
      @app.route('/', methods=['GET'])
      def handle_request():
          threads = []
          for _ in range(7):
              thread = threading.Thread(target=process_sub_task)
              threads.append(thread)
              thread.start()
          for thread in threads:
              thread.join()
          return 'Request processed successfully'
      if __name__ == '__main__':
          app.run(threaded=True)
      

      handle_request函数仍然是接口的入口点。当收到一个请求时,它会创建7个子线程,并将每个子线程的目标函数设置为process_sub_task。

      在process_sub_task函数内部,你可以编写具体的处理逻辑,根据需要执行相应的操作。

      通过这种方式,你可以同时并发处理7个子线程任务,以加快每个请求任务的处理速度。每个子线程在自己的上下文中独立执行,以实现并行处理。

      三、并发处理10个进程任务

      下面是一个示例代码,展示了如何使用线程池来实现并发处理10个任务:

      from flask import Flask
      import multiprocessing
      app = Flask(__name__)
      def process_request():
          # 这里是每个进程请求任务需要执行的逻辑
          pass
      @app.route('/', methods=['GET'])
      def handle_request():
          processes = []
          for _ in range(10):
              process = multiprocessing.Process(target=process_request)
              processes.append(process)
              process.start()
          for process in processes:
              process.join()
          return 'Request processed successfully'
      if __name__ == '__main__':
          app.run(threaded=True)
      

      handle_request函数仍然是接口的入口点。当收到一个请求时,它会创建10个进程,并将每个进程的目标函数设置为process_request。

      在process_request函数内部,你可以编写具体的处理逻辑,根据需要执行相应的操作。

      通过这种方式,你可以同时并发处理10个进程请求任务。每个进程在自己的上下文中独立执行,以实现并行处理。

      四、综合处理多进程、多线程(任务需求)

      from flask import Flask
      import multiprocessing
      import threading
      app = Flask(__name__)
      def process_sub_task():
          # 这里是每个子线程任务需要执行的逻辑
          pass
      def process_request():
          threads = []
          for _ in range(7):
              thread = threading.Thread(target=process_sub_task)
              threads.append(thread)
              thread.start()
          for thread in threads:
              thread.join()
      @app.route('/', methods=['GET'])
      def handle_request():
          processes = []
          for _ in range(10):
              process = multiprocessing.Process(target=process_request)
              processes.append(process)
              process.start()
          for process in processes:
              process.join()
          return 'Request processed successfully'
      if __name__ == '__main__':
          app.run(threaded=True)
      

      在这个示例代码中,handle_request函数仍然是接口的入口点。当收到一个请求时,它会创建10个进程,并将每个进程的目标函数设置为process_request。

      在process_request函数内部,我们又创建了7个子线程来并发处理任务,每个任务执行process_sub_task函数。

      通过这种方式,你可以同时并发处理10个进程请求任务,并且每个进程任务内部有7个子线程来加快处理速度。每个进程和线程在自己的上下文中独立执行,以实现并行和加速处理。