Python 多线程

一、线程的使用

需导入模块: from threading import Thread

二、基本使用

 1 def fun1(arg1, v):
 2     print(arg1)
 3 
 4 print('before')
 5 t1 = Thread(target=fun1, args=('aaa',11,))
 6 t1.start()
 7 print('此线程名称:', t1.getName())
 8 
 9 t2 = Thread(target=fun1, args=('bbb',22,))
10 t2.start()
11 print('此线程名称:', t2.getName())
12 
13 print('after')
View Code

三、常用方法

  • start
  • getName()
  • setName()
  • isDaemon()
  • setDaemon()
  • join(timeout)
  • run()
 1 def fun2():
 2     for i in range(100):
 3         print(i)
 4         time.sleep(1)
 5 
 6 print('start')
 7 t1 = Thread(target=fun2)
 8 print('是否守护线程:', t1.isDaemon())     #默认为False,自动执行
 9 #设置为守护线程,不自动执行,主程序执行完则子线程不执行,
10 #主程序如果没执行完,则子线程随着主程序执行,直至主程序结束,子线程也跟着结束
11 t1.setDaemon(True)
12 t1.start()
13 print('after1')
14 print('after2')
15 print('after3')
16 time.sleep(10)
View Code
 1 def fun1():
 2     for i in range(10):
 3         print(i)
 4         time.sleep(1)
 5 
 6 print('before')
 7 t1 = Thread(target=fun1)
 8 t1.start()
 9 # t1.join()   #主程序执行到join()这里后挺住开始执行子线程,子线程执行结束后主程序继续执行
10 t1.join(5)    #最多等5秒,子线程最多执行5秒后主进程继续向下执行,主程序执行结束后,子线程继续执行
11 
12 print('after')
View Code

 

四、自定义线程类

 1 class MyThread(Thread):
 2     def run(self):
 3         time.sleep(3)
 4         print('我是线程')
 5         Thread.run(self)    #如果不加此句,则不会执行自定义线程中的函数
 6 
 7 def Bar():
 8     print('bar')
 9 
10 t1 = MyThread(target=Bar)
11 t1.start()
12 print('over')
View Code


五、自定义线程类应用 -- 生产者消费者模型

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from queue import Queue
 5 from threading import Thread
 6 import time
 7 import random
 8 
 9 class Producer(Thread):
10     def __init__(self, name, queue):
11         '''
12         生产者初始化
13         :param name:生产者名称
14         :param queue:容器
15         '''
16         self.__Name = name
17         self.__Queue = queue
18         super(Producer, self).__init__()    #调用父类构造方法
19 
20     def run(self):
21         while True:
22             if self.__Queue.full():
23                 time.sleep(random.randrange(5))
24             else:
25                 self.__Queue.put('包子')
26                 time.sleep(random.randrange(5))
27                 print('%s %s 生产了一个包子' %(self.__Name, time.strftime('%Y-%m-%d %H:%M:%S')))
28             # Thread.run(self)
29 
30 class Customer(Thread):
31     def __init__(self, name, queue):
32         '''
33         消费者初始化
34         :param name:消费者名称
35         :param queue: 容器
36         '''
37         self.__Name = name
38         self.__Queue = queue
39         super(Customer, self).__init__()
40 
41     def run(self):
42         while True:
43             # print('qsize=',self.__Queue.qsize())
44             if self.__Queue.empty():
45                 time.sleep(random.randrange(5))
46             else:
47                 self.__Queue.get_nowait()
48                 time.sleep(random.randrange(3))
49                 print('%s %s 消费了一个包子,还剩%d个包子' %(self.__Name, time.strftime('%Y-%m-%d %H:%M:%S'), self.__Queue.qsize()))
50             # Thread.run(self)
51 
52 que = Queue(maxsize=100)
53 
54 # print(que.qsize())
55 
56 liFu = Producer('李师傅', que)
57 liFu.start()
58 
59 zhangFu = Producer('张师傅', que)
60 zhangFu.start()
61 
62 wangFu = Producer('王师傅', que)
63 wangFu.start()
64 
65 for item in range(20):
66     name = '陈涛%d' %(item,)
67     temp = Customer(name, que)
68     temp.start()
69 
70 
71 # print(que.qsize())
72 
73 
74 # print(que.qsize())
75 # que.put('1')
76 # que.put('2')
77 # print('empty: ', que.empty())
78 # print(que.qsize())
79 # que.get()
80 # que.get()
81 # print('empty: ', que.empty())
View Code


六、函数编程实现生产者消费者模型

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import time
 5 import threading
 6 import random
 7 import queue
 8 
 9 def Producer(name, que):
10     while True:
11         if que.qsize()<3:
12             que.put('包子')
13             print('%s 生产了一个包子' % name)
14         else:
15             print('还有3个包子')
16         time.sleep(random.randrange(2))
17 
18 def Customer(name, que):
19     while True:
20         try:
21             que.get_nowait()
22             print('%s 消费了一个包子' % name)
23         except Exception:
24             print('没有包子了...')
25         time.sleep(random.randrange(3))
26 
27 que = queue.Queue(100)
28 
29 xf1 = threading.Thread(target=Producer,args=('师傅1',que))
30 xf1.start()
31 xf2 = threading.Thread(target=Producer,args=('师傅2',que))
32 xf2.start()
33 
34 xli = threading.Thread(target=Customer,args=('小李',que))
35 xli.start()
36 xzh = threading.Thread(target=Customer,args=('小张',que))
37 xzh.start()
View Code


七、线程锁

 1 #!/usr/bin/evn python
 2 # -*- coding:utf-8 -*-
 3 
 4 import threading
 5 import time
 6 
 7 num = 0
 8 
 9 def fun1(n):
10     time.sleep(1)
11     global num
12     lock.acquire()  # 需要锁,会独占CPU的操作,此句应放在对数据操作的时候
13     num += 1
14     lock.release()  #释放锁,对数据操作完后要把锁释放掉,在没有释放前,不可以再添加需要锁
15     # time.sleep(0.01)  如果还有sleep一会,则表示此时不需CPU处理,则下面的print就不会按顺序输出
16     print(num)  #如果释放锁后直接print,则是CPU锁定刚结束,还占用着CPU,则会按顺序输出
17 
18 lock = threading.Lock() #线程锁
19 
20 for i in range(100):
21     t = threading.Thread(target=fun1, args=('n',))
22     t.start()
View Code


八、递归线程锁 #一般不常用

 1 #!/usr/bin/evn python
 2 # -*- coding:utf-8 -*-
 3 
 4 import threading
 5 import time
 6 
 7 num = 0
 8 num2 = 0
 9 
10 def fun1(n):
11     time.sleep(1)
12     global num
13     global num2
14     lock.acquire()  # 需要锁,会独占CPU的操作,此句应放在对数据操作的时候
15     num += 1
16     lock.acquire()  #使用递归锁就可以在锁内嵌套锁
17     num2 += 1
18     lock.release()  #使用递归锁必须要把请求道的锁这个释放
19     lock.release()
20     print(num, num2)
21 
22 lock = threading.RLock() #线程锁
23 
24 for i in range(100):
25     t = threading.Thread(target=fun1, args=('n',))
26     t.start()
View Code


九、同时进行多个线程

 1 #!/usr/bin/evn python
 2 # -*- coding:utf-8 -*-
 3 
 4 import threading
 5 import time
 6 
 7 num = 0
 8 
 9 def fun1(n):
10     time.sleep(1)
11     global num
12     samp.acquire()  # 需要锁,会独占CPU的操作,此句应放在对数据操作的时候
13     num += 1
14     print(num)
15     samp.release()  #释放锁,对数据操作完后要把锁释放掉,在没有释放前,不可以再添加需要锁
16 
17 # lock = threading.Lock() #线程锁
18 samp = threading.BoundedSemaphore(5)    #设置此锁最多同时可以几个进行进行数据修改
19 
20 for i in range(200):
21     t = threading.Thread(target=fun1, args=('n',))
22     t.start()
View Code


十、线程间的信息交互

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import threading
 5 import time
 6 
 7 def producer():
 8     print('收银员等人来买包子')
 9     event.wait()    #等待消息变化,等待有进程执行set()返回True
10     event.clear()   #等到set()变成True了,则恢复set()的状态
11 
12     print('收银员:有人来买包子')
13     print('收银员:给他做一个包子')
14     time.sleep(3)
15 
16     print('收银员:给你包子')
17     event.set()
18 
19 
20 def customer():
21     print('张三来买包子')
22     event.set()
23 
24     time.sleep(1)
25     print('张三:等待取包子')
26 
27     event.wait()
28     event.clear()
29     print('张三:谢谢')
30 
31 event = threading.Event()   #线程间可以互通消息的变量
32 
33 kf = threading.Thread(target=producer)
34 kf.start()
35 zs = threading.Thread(target=customer)
36 zs.start()
View Code

 

posted @ 2016-11-27 19:47  taibai  阅读(206)  评论(0编辑  收藏  举报