`

Python多线程学习-叁-threading

 
阅读更多

 

Python 多线程threading学习

 

 

上一节学习了threading.Lockthreading.RLockthreading.Condition,如果全部理解的话,同步方面的知识应该不错的了。threading还有一个Event类,这个类也是用来同步的,不过这个类提供线程之间的模型也最为简单,了解即可。其实对于熟悉Condition的来说,Event就不是特别必要了。不过有时候线程的事情未必会需要Condition,能用个轻量级的Event解决就不必使用牛刀了。

 

 

Event的说明如下:

 

This is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it.

An event object manages an internal flag that can be set to true with the set() method and reset to false with the clear() method. The wait() method blocks until the flag is true.

 

 

这个看说明就知道什么意思。只是把锁包装一下,添加wait方法。算是锁最近单的实现了。

 

 

唯一需要注意的是wait方法的解释:

 

wait([timeout])
           Block until the internal flag is true. If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs.

 

 

这个wait是个阻塞操作,这点使用时要注意。

 

 

#encoding=gbk
import threading  
import time  
  
class MyThread(threading.Thread):  
    def __init__(self, signal):  
        threading.Thread.__init__(self)  
        self.singal = signal  
          
    def run(self):  
        print "I am %s,I will sleep ..."%self.name  
        self.singal.wait()  
        print "I am %s, I awake..." %self.name  
          
if __name__ == "__main__":  
    singal = threading.Event()  
    for t in range(0, 3):  
        thread = MyThread(singal)  
        thread.start()  
    print "main thread sleep 3 seconds... "  
    time.sleep(3)  
    singal.set() 
 

 

后面还有一个Semaphore类,这个类的说明如下:

 

This is one of the oldest synchronization primitives in the history of computer science, invented by the early Dutch computer scientist Edsger W. Dijkstra (he used P() and V() instead of acquire() and release()).

A semaphore manages an internal counter which is decremented by each acquire() call and incremented by each release() call. The counter can never go below zero; when acquire() finds that it is zero, it blocks, waiting until some other thread calls release().
 

 

按照解释,semaphore管理一个内置的计数器,调用acquire方法是-1,调用release方法时+1,负责某个资源可以使用的线程数。实际上是控制在某个资源上,同时可以上几把锁,有几个线程来访问。semephore的构造方法能够选择选择内置计数器的初始值,默认初始值为1

这个结合ConditionEvent的思路就清楚了,实际上是在锁上添加了限制。

 

 

#encoding=gbk

import threading
import time

class semaphore_thread(threading.Thread):
  def __init__(self,semaphore):
    threading.Thread.__init__(self);
    self.semaphore = semaphore

  def run(self):
    if semaphore.acquire():
      print "%s get semaphore" %(threading.currentThread().getName())
      time.sleep(3)
      semaphore.release()
      print "%s release semaphore" %(threading.currentThread().getName())

if __name__ == "__main__":
  semaphore = threading.Semaphore(3)
  for i in range(10):
    t=semaphore_thread(semaphore)
    t.start()
 

根据输出结果,可以看到在同一个时刻,最多只能有三个线程获得锁运行,其它线程都处于等待状态,实现资源的控制。

 

 

另外threading模块还有个BounderSemaphore,这个是个Factory function,直接返回一个bounded semaphore,这个BoundedSemaphore能够确保当前值不会大于初始值,否则ValueError会被抛出来。其实这个BoundedSemaphore就是Semaphore添加边界检查的功能,不再举例了。

 

 

threading包到这里就告一段落了,回顾一下,我们学习了如下类:

 

 

threading.Thread
threading.Timer
threading.Lock
threading.RLock
threading.Condition
threading.Event
threading.Semaphore
threading.BoundedSemaphore
 

 

这些类的熟练使用能够保证你准确安全的使用并发多线程。

不过学习完多线程就Ok了?No,这些线程的使用实际上是单个Processor流转处理各个Thread,这个确实很快,至少我们感觉不出来。

不过对于多Processor的处理,使用线程模型只是利用了有限的Processor,同样Python提供了multiprocessing包来提升多核的处理能力。这个算是threading的进阶,有时间的话会分析下multiprocessing的处理过程。

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics