• 【廖雪峰老师python教程】——进程与线程


    多进程


    • 操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。
    • 对于操作系统来说,一个任务就是一个进程(Process)
    • 在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
    • multiprocessing模块就是跨平台版本的多进程模块
      from multiprocessing import Process
      import os
      
      # 子进程要执行的代码
      def run_proc(name):
          print('Run child process %s (%s)...' % (name, os.getpid()))
      
      if __name__=='__main__':
          print('Parent process %s.' % os.getpid())
          p = Process(target=run_proc, args=('test',))
          print('Child process will start.')
          p.start()
          p.join()#等待子进程结束,才继续往下进行
          print('Child process end.')
      Parent process 928.
      Process will start.
      Run child process test (929)...
      Process end.
    • 进程池
      from multiprocessing import Pool
      import os, time, random
      
      def long_time_task(name):
          print('Run task %s (%s)...' % (name, os.getpid()))
          start = time.time()
          time.sleep(random.random() * 3)
          end = time.time()
          print('Task %s runs %0.2f seconds.' % (name, (end - start)))
      
      if __name__=='__main__':
          print('Parent process %s.' % os.getpid())
          p = Pool(4)
          for i in range(5):
              p.apply_async(long_time_task, args=(i,))
          print('Waiting for all subprocesses done...')
          p.close()# 必须先关闭,才能停止添加进程,才能运行
          p.join()
          print('All subprocesses done.')
      Parent process 669.
      Waiting for all subprocesses done...
      Run task 0 (671)...
      Run task 1 (672)...
      Run task 2 (673)...
      Run task 3 (674)...
      Task 2 runs 0.14 seconds.
      Run task 4 (673)...
      Task 1 runs 0.27 seconds.
      Task 3 runs 0.86 seconds.
      Task 0 runs 1.41 seconds.
      Task 4 runs 1.91 seconds.
      All subprocesses done.

    多线程


    • import time, threading
      
      # 新线程执行的代码:
      def loop():
          print('thread %s is running...' % threading.current_thread().name)
          n = 0
          while n < 5:
              n = n + 1
              print('thread %s >>> %s' % (threading.current_thread().name, n))
              time.sleep(1)
          print('thread %s ended.' % threading.current_thread().name)
      
      print('thread %s is running...' % threading.current_thread().name)
      t = threading.Thread(target=loop, name='LoopThread')
      t.start()
      t.join()
      print('thread %s ended.' % threading.current_thread().name)
    • 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。【锁机制】
      balance = 0
      lock = threading.Lock()
      
      def run_thread(n):
          for i in range(100000):
              # 先要获取锁:
              lock.acquire()
              try:
                  # 放心地改吧:
                  change_it(n)
              finally:
                  # 改完了一定要释放锁:
                  lock.release()
    • 多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。

      Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦

    ThreadLocal


    • 在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。

      但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦:

    一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题。

    import threading
    
    # 创建全局ThreadLocal对象:
    local_school = threading.local()
    
    def process_student():
        # 获取当前线程关联的student:
        std = local_school.student
        print('Hello, %s (in %s)' % (std, threading.current_thread().name))
    
    def process_thread(name):
        # 绑定ThreadLocal的student:
        local_school.student = name
        process_student()
    
    t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
    t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    Hello, Alice (in Thread-A)
    Hello, Bob (in Thread-B)

    • 对应到Python语言,单线程的异步编程模型称为协程,有了协程的支持,就可以基于事件驱动编写高效的多任务程序。

    分布式进程


    • 在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上
    • 后期可以学习,现在用不上



  • 相关阅读:
    python多版本切换
    python之禅
    Python int与string之间的转化
    pycharm工具使用
    python学习路线图
    traceback.print_exc()的用法
    他人学习Python感悟
    【西北师大-19软工】第十三、十四次作业汇总暨期末总结
    【西北师大-19软工】第十二次作业成绩汇总
    第十七周助教工作总结——NWNU李泓毅
  • 原文地址:https://www.cnblogs.com/ChaoyuanJam/p/9749718.html
Copyright © 2020-2023  润新知