1. 多线程库threading

    1. 方法

      Thread(target=func,args=()):创建一个线程对象

      local():创建一个ThreadLocal对象

      active_count():返回当前存活的线程对象的数量;通过计算len(threading.enumerate())长度而来

      current_thread():返回当前线程对象

      enumerate():返回当前存在的所有线程对象的列表

      get_ident():返回线程pid

      main_thread():返回主线程对象,类似 threading.current_thread();只不过一个是返回当前线程对象,一个是返回主线程对象

      is_alive():是否存活

    2. 同步

      acquire()/release():获得/释放 Lock

    3. Lock

      多个线程同时acquire时,只能获取一把锁,其他线程等待到获得锁为止

    4. 可重入锁,也叫做递归锁 RLock

      在需要重复获得锁的情况下(如:递归调用)避免死锁!!!

      多个线程同时acquire时,都可以获得锁,所以acquire,release必须成对

    5. Condiftion

      wait():线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。调用wait()会释放Lock,直至该线程被Notify()、NotifyAll()或者超时线程又重新获得Lock.

      notify(n=1):通知其他线程,那些挂起的线程接到这个通知之后会开始运行,默认是通知一个正等待该condition的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。notify()不会主动释放Lock。

      notifyAll():如果wait状态线程比较多,notifyAll的作用就是通知所有线程(这个一般用得少)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      #!/usr/bin/python3.4
      # -*- coding: utf-8 -*-

      import threading, time

      def Seeker(cond, name):
      time.sleep(2)
      cond.acquire()
      print('%s :我已经把眼睛蒙上了!'% name)
      cond.notify()
      cond.wait()
      for i in range(3):
      print('%s is finding!!!'% name)
      time.sleep(2)
      cond.notify()
      cond.release()
      print('%s :我赢了!'% name)

      def Hider(cond, name):
      cond.acquire()
      cond.wait()
      for i in range(2):
      print('%s is hiding!!!'% name)
      time.sleep(3)
      print('%s :我已经藏好了,你快来找我吧!'% name)
      cond.notify()
      cond.wait()
      cond.release()
      print('%s :被你找到了,唉~^~!'% name)

      if __name__ == '__main__':
      cond = threading.Condition()
      seeker = threading.Thread(target=Seeker, args=(cond, 'seeker'))
      hider = threading.Thread(target=Hider, args=(cond, 'hider'))
      seeker.start()
      hider.start()
      执行结果:
      seeker :我已经把眼睛蒙上了!
      hider is hiding!!!
      hider is hiding!!!
      hider :我已经藏好了,你快来找我吧!
      seeker is finding!!!
      seeker is finding!!!
      seeker is finding!!!
      seeker :我赢了!
      hider :被你找到了,唉~^~!
    6. Semaphore和BoundedSemaphore

      Semaphore:Semaphore 在内部管理着一个计数器。调用 acquire() 会使这个计数器 -1,release() 则是+1(可以多次release(),所以计数器的值理论上可以无限).计数器的值永远不会小于 0,当计数器到 0 时,再调用 acquire() 就会阻塞,直到其他线程来调用release()

      Bmaphore:类似于Semaphore;不同在于BoundedSemaphore 会检查内部计数器的值,并保证它不会大于初始值,如果超了,就引发一个 ValueError。多数情况下,semaphore 用于守护限制访问(但不限于 1)的资源,如果 semaphore 被 release() 过多次,这意味着存在 bug

  2. 系统交互库subprocess

    1. 特性

      1. 多用于调用外部程序
      2. 只通过管道进行文本交流
    2. 方法

      call():执行命令,并返回执行状态,其中shell参数为False时,命令需要通过列表的方式传入,当shell为True时,可直接传入命令

      check_call():用法与subprocess.call()类似,区别是,当返回值不为0时,直接抛出异常

      check_output():用法与上面两个方法类似,区别是,如果当返回值为0时,直接返回输出结果,如果返回值不为0,直接抛出异常。需要说明的是,该方法在python3.x中才有。

      Popen():在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等,该方法有以下参数:

      args:shell命令,可以是字符串,或者序列类型,如list,tuple。

      bufsize:缓冲区大小,可不用关心

      stdin,stdout,stderr:分别表示程序的标准输入,标准输出及标准错误

      shell:与上面方法中用法相同

      cwd:用于设置子进程的当前目录

      env:用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量

      universal_newlines:不同系统的的换行符不同,当该参数设定为true时,则表示使用\n作为换行符

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      import subprocess

      obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      obj.stdin.write('print 1 \n')
      obj.stdin.write('print 2 \n')
      obj.stdin.write('print 3 \n')
      obj.stdin.write('print 4 \n')
      obj.stdin.close()

      cmd_out = obj.stdout.read()
      obj.stdout.close()
      cmd_error = obj.stderr.read()
      obj.stderr.close()

      print cmd_out
      print cmd_error
      1
      2
      3
      4
      5
      6
      7
      #将一个子进程的输出,作为另一个子进程的输入:

      import subprocess
      child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
      child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
      out = child2.communicate()

  3. 异步高级封装接口concurrent.futures
    ThreadPoolExecutor,ProcessPoolExecutor
    1
    2
    3
    4
    5
    6
    7
    8
    with futures.ThreadPoolExecutor(workers) as executor:  
    res = executor.map(func, iter)

    executor = ThreadPoolExecutor(max_workers=2)
    a = executor.submit(funca)
    b = executor.submit(funcb)
    resa = a.result()
    resb = b.result()
    ProcessPoolExecutor使用方式与ThreadPoolExecutor一样
  4. 多进程管理包multiprocessing

    1. 待续