标签:
1.threading.Thread对象【创建线程的主要对象】:
方法:start():启动线程
run():启动线程后自动调用的方法
join([timeout]):等待到被调用的线程终止
is_alive():返回线程活动状态
属性:name:线程名
ident:线程ID号
daemon:后台标志
2.创建线程的方法:
1:实例化threading.Thread对象
ths = threading.Thread( target = None, name = None, args = (), kwarg = {} )
传入函数名 线程名 函数的参数
2:继承threading中的Thread对象后再实例化并启动
3.以不同的线程类型分:
令:t = threading.Thread(target=dmn...),即是t为一个线程
3.1.独立线程:就是最简单的独立单线程
3.2.线程等待:t.join([timeout]),放到start()后,表明t线程执行完后(或是指定时间后)才轮到下一个线程【若是因为指定时间的话还会跳回t线程】
1 #coding:utf-8 2 import threading, time 3 class MyThread(threading.Thread): 4 5 def run(self): 6 for i in range(40): 7 print() #若是t线程在执行时就是打印换行 8 time.sleep(0.1) 9 10 if __name__ == "__main__": 11 t = MyThread() 12 t.start() 13 **t.join()** 14 for i in range(10): #此部分是主线程执行的,也就是说此程序有主线程与t线程两个线程 15 print("main:", i) 16 time.sleep(0.1) 17 18 #最后会在打印完了换行后才打印0到9的“main:...”, 说明t线程执行完了后主线程才执行的
3.3.后台线程(在主线程退出后立即自杀):设置daemon属性为True【 t.daemon = True】
3.4.线程同步:指的是多个线程同时需要用到的资源,此时为了保证一致性有多种不同的加锁处理机制【获取了锁的线程可以对此资源进行操作,而没有的线程处于阻塞状态】,如下:
1)先到先用---指令锁:threading.Lock对象
定义锁变量:lock = threading.Lock()
锁定资源:lock.acquire()
释放资源:lock.release()
1 import threading, time, random 2 share = 4 3 class MyThread(threading.Thread): 4 def __init__(self,i): 5 super().__init__() 6 self.i = i 7 8 def run(self): 9 global share 10 for d in range(40): 11 **lock.acquire()** 12 print(share) 13 share += self.i 14 time.sleep(random.random()) 15 print("t+", self.i, "=", share) 16 **lock.release()** 17 18 **lock = threading.Lock()** 19 20 if __name__ == "__main__": 21 t = MyThread(2) 22 tt = MyThread(6) 23 t.start() 24 # t.join() 25 tt.start() 26 27 #会看到一会儿加2,一会儿加6 28 #若将倒数第二行注释去除,则一直加2,完了后才加6
2)可重入锁:被某一线程锁定了后还可以被其他线程锁定
3)有先后顺序的使用---条件变量:threading.Condition对象(创建了一个带锁的线程池), [当具备了某条件后才调用某线程,如生产者-消费者模式]
定义锁变量:conLock = threading.Condition()
获得锁:conLock.acquire()
通知线程池里其他线程:conLock.notify( [ n=x ] )【唤起x个,默认为1】,clock.notify_all()【唤醒全部】
释放锁并且进入线程池等待:conLock.wait()
1 #coding:utf-8 2 import threading, time 3 share = 0 4 **share_condition = threading.Condition()** 5 6 class ProductThread(threading.Thread): 7 def __init__(self): 8 super().__init__() 9 self.name = "生产者" 10 11 def run(self): 12 global share 13 if share_condition.acquire(): 14 while True: 15 if not share: 16 share += 1 17 print( self.name, share ) 18 **share_condition.notify()** #执行线程池里的一个等待线程 19 **share_condition.wait()** #当前线程释放锁并将当前线程放入线程池等待下次notify(),所以如果没有此句则只会显示一句“生产者:1” 20 time.sleep(1) 21 22 class CustumerThread(threading.Thread): 23 def __init__(self): 24 super().__init__() 25 self.name = "消费者" 26 27 def run(self): 28 global share 29 if share_condition.acquire(): 30 while True: 31 if share: 32 share -= 1 33 print( self.name, share ) 34 **share_condition.notify()** 35 **share_condition.wait()** 36 time.sleep(1) 37 38 lock = threading.Lock() 39 40 if __name__ == "__main__": 41 product = ProductThread() 42 customer = CustumerThread() 43 product.start() 44 customer.start() 45 46 47 #最后会相继打印: 48 # 生产者 1 49 # 消费者 0
4)部分线程同时使用---信号量:threading.Semaphore对象
定义锁:sema = threading.Semaphore(n) #允许同时有n个线程获得锁
获得锁:sema.acquire()
释放锁:sema.release()
常用于限制资源的访问,比如数据库的连接池
1 #coding:utf-8 2 import threading, time 3 class MyThread(threading.Thread): 4 def __init__(self,name): 5 super().__init__() 6 self.name = name 7 8 def run(self): 9 if sema.acquire(): 10 print(self.name,"得到了锁") 11 time.sleep(1) 12 sema.release() 13 print(self.name,‘释放了锁‘) 14 15 sema = threading.Semaphore(2) 16 17 if __name__ == "__main__": 18 threads = [ MyThread(str(i)+"sema") for i in range(5) ] 19 for thread in threads: 20 thread.start() 21 22 #输出如下,可以看出同时能够有两个线程获得了锁 23 # 0sema 得到了锁 24 # 1sema 得到了锁 25 # 0sema 释放了锁 26 # 1sema 释放了锁 27 # 2sema 得到了锁 28 # 3sema 得到了锁 29 # 2sema 释放了锁 30 # 4sema 得到了锁 31 # 3sema 释放了锁 32 # 4sema 释放了锁
5)线程间通信---threading.Event对象(创建了一个带有标志的线程池,当一个线程设置内部标志为True后线程池中的等待线程就会被唤醒并执行)【即是当前执行线程可以决定啥时候(一般是所共同使用的资源已经使用完毕了后)“叫醒”别的线程,需要注意的是,若此时叫醒别人的线程并没有wait进入线程池,那么如果其还有代码的话将继续执行下去】
定义锁变量: event = threading.Event()
进入线程池等待:event.wait([timeout])
设置内部标志为True:event.set() <---> event.clear()
1 #coding:utf-8 2 import threading, time 3 4 class WaitThread(threading.Thread): 5 6 def run(self): 7 self.name = "等待线程" 8 print(self.name,"正在等待") #注意此程序的执行顺序,先调用的此线程执行到这里 9 **event.wait()** #在此此线程wait进入线程池等待,切换到mainThread直至设置标志 10 print(self.name,"启动了") #从而此线程在此被唤醒执行 11 **event.clear()** #而后设置标志为false 12 13 class MainThread(threading.Thread): 14 15 def run(self): 16 time.sleep(3) 17 print("主线程更改了标志") 18 **event.set()** 19 print("这里的会在WaitThread打印启动了前打印吗?") 20 21 **event = threading.Event()** 22 23 if __name__ == "__main__": 24 wt = WaitThread() 25 mt = MainThread() 26 wt.start() 27 mt.start() 28 29 # 输出: 30 # 等待线程 正在等待 31 # 主线程更改了标志 32 # 这里的会在WaitThread打印启动了前打印吗? 33 # 等待线程 启动了
*补充.关于定时执行:threading.Timer()
标签:
原文地址:http://www.cnblogs.com/pengsixiong/p/5557720.html