Python开发Day9(多线程多进程)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python开发Day9(多线程多进程)相关的知识,希望对你有一定的参考价值。

python线程:

  • 介绍:

    • Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。

  • 使用:

    • Threading方法

      • .start() : 激活线程
      • .getName(): 获取线程的名称
      • .setName() : 设置线程的名称 
      • .name : 获取或设置线程的名称
      • .is_alive() : 判断线程是否为激活状态
      • .isAlive() :判断线程是否为激活状态
      • .setDaemon() 设置为后台线程或前台线程(默认:False);通过一个布尔值设置线程是否为守护线程,必须在执行start()方法之后才可以使用。如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止;如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
      • .isDaemon() : 判断是否为守护线程
      • .ident :获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才有效,否则它只返回None。
      • .join() :逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
      • .run() :线程被cpu调度后自动执行线程对象的run方法
    • 直接使用未加锁:
      技术分享
      import threading
      
      lock = threading.RLock()#定义一个线程锁
      def worker(num):
          print("Thread %d" % num)
      
      for i in range(20):
          t = threading.Thread(target=worker,args=(i,),name="t.%d" % i)
          t.start()#激活线程
      
      执行结果:
      Thread 0
      Thread 1
      Thread 2
      Thread 6
      Thread 4
      Thread 3
      Thread 5
      Thread 8
      Thread 10
      Thread 9
      Thread 7
      Thread 13
      Thread 12
      Thread 11
      Thread 16
      Thread 14
      Thread 15
      Thread 19
      Thread 18
      Thread 17
      View Code
    • 使用加锁:
      技术分享
      import threading
      lock = threading.RLock()#定义一个线程锁
      def worker(num):
          lock.acquire()#加锁
          print("Thread %d" % num)
          lock.release()#解锁
      
      for i in range(20):
          t = threading.Thread(target=worker,args=(i,),name="t.%d" % i)
          t.start()#激活线程
      
      执行结果:
      Thread 0
      Thread 1
      Thread 2
      Thread 3
      Thread 4
      Thread 5
      Thread 6
      Thread 7
      Thread 8
      Thread 9
      Thread 10
      Thread 11
      Thread 12
      Thread 13
      Thread 14
      Thread 15
      Thread 16
      Thread 17
      Thread 18
      Thread 19
      View Code
    • 线程锁有两种一种为RLock一种为Lock
      • Lock解析:
        技术分享
        lock = threading.Lock()#定义一个线程锁
        lock.acquire()#加锁
        print(123)
        lock.acquire()#加锁           产生了死锁
        print(234)
        lock.release()#解锁
        print(345)
        lock.release()#解锁
                #死锁,自己加锁后再次申请锁自己等待自己释放锁。
        
        执行结果:
        123
        一直等待~~~~~~~~~~
        View Code
      • RLock解析:
        技术分享
        lock = threading.RLock()#定义一个线程锁
        lock.acquire()#加锁
        print(123)
        lock.acquire()#加锁
        print(234)
        lock.release()#解锁
        print(345)
        lock.release()#解锁
                #他不会产生死锁,但是需要注意产生了多少锁需要释放多少锁
        
        执行结果:
        123
        234
        345
        View Code

 

线程间的通讯使用Event

 

    • 介绍:

      • Event是线程间通信最间的机制之一:一个线程发送一个event信号,其他的线程则等待这个信号。用于主线程控制其他线程的执行。 Events 管理一个flag,这个flag可以使用set()设置成True或者使用clear()重置为False,wait()则用于阻塞,在flag为True之前。flag默认为False。

    • 使用:

      • Event.wait([timeout]) : 堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。

      • Event.set() :将标识位设为Ture

      • Event.clear() : 将标识伴设为False。

      • Event.isSet() :判断标识位是否为Ture。

      • 代码举例:

        技术分享
        import threading
         
        def do(event):
            print(start)
            event.wait()
            print(execute)
         
        event_obj = threading.Event()
        for i in range(10):
            t = threading.Thread(target=do, args=(event_obj,))
            t.start()
         
        event_obj.clear()
        inp = input(input:)
        if inp == true:
            event_obj.set()
        
        执行结果:
        start
        start
        start
        start
        start
        input:true
        execute
        execute
        execute
        execute
        execute
        View Code

        当线程执行的时候,如果flag为False,则线程会阻塞,当flag为True的时候,线程不会阻塞。它提供了本地和远程的并发性。

 

 

queue模块:

  • 介绍:
    • Queue 就是对队列,它是线程安全的(举例来说,我们去肯德基吃饭。厨房是给我们做饭的地方,前台负责把厨房做好的饭卖给顾客,顾客则去前台领取做好的饭。这里的前台就相当于我们的队列。

      这个模型也叫生产者-消费者模型。

  • 使用:
    • 方法:
      import queue
      
      q = queue.Queue(maxsize=0)  # 构造一个先进显出队列,maxsize指定队列长度,为0 时,表示队列长度无限制。
      
      q.join()    # 等到队列为kong的时候,在执行别的操作
      q.qsize()   # 返回队列的大小 (不可靠)
      q.empty()   # 当队列为空的时候,返回True 否则返回False (不可靠)
      q.full()    # 当队列满的时候,返回True,否则返回False (不可靠)
      q.put(item, block=True, timeout=None) #  将item放入Queue尾部,item必须存在,可以参数block默认为True,表示当队列满时,会等待队列给出可用位置,
                               为False时为非阻塞,此时如果队列已满,会引发queue.Full 异常。 可选参数timeout,表示 会阻塞设置的时间,过后,
                                如果队列无法给出放入item的位置,则引发 queue.Full 异常
      q.get(block=True, timeout=None) #   移除并返回队列头部的一个值,可选参数block默认为True,表示获取值的时候,如果队列为空,则阻塞,为False时,不阻塞,
                            若此时队列为空,则引发 queue.Empty异常。 可选参数timeout,表示会阻塞设置的时候,过后,如果队列为空,则引发Empty异常。
      q.put_nowait(item) #   等效于 put(item,block=False)
      q.get_nowait() #    等效于 get(item,block=False)

       

    • 使用:
      技术分享
      import threading,queue
      message = queue.Queue(10)
      
      def producer(i):
          print(>>>>>,i)
          message.put(i)
      
      
      def consumer(i):
          msg = message.get()
          print(date,msg)
      
      
      for i in range(12):
          t = threading.Thread(target=producer, args=(i,))
          t.start()
      
      for i in range(10):
          t = threading.Thread(target=consumer, args=(i,))
          t.start()
      
      
      执行结果:
      >>>>> 0
      >>>>> 1
      >>>>> 2
      >>>>> 3
      >>>>> 4
      >>>>> 5
      >>>>> 6
      >>>>> 7
      >>>>> 8
      >>>>> 9
      >>>>> 10
      >>>>> 11
      date 0
      date 1
      date 2
      date 3
      date 4
      date 5
      date 6
      date 7
      date 8
      date 9
      View Code

       

       

 

以上是关于Python开发Day9(多线程多进程)的主要内容,如果未能解决你的问题,请参考以下文章

day9-01 线程

day9---多线程,线程锁,队列

day9---多线程,线程锁,队列

day9---多线程,线程锁,队列

day9--多线程与多进程

Python-Cpython解释器支持的进程与线程-Day9