python-线程进程与队列

线程,有时被称为轻量级进程,是程序执行流的最小单元
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指进行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
python中多个cpu无法同时处理一个进程或其子进程,多个cpu可以同时处理多个线程
1
import time 2 def f1(arg): 3 time.sleep(1) 4 print(arg) 5 import threading 6 t = threading.Thread(target = f1,args = (123,)) 7 #t.setDaemon(True)#表示主线程不等子线程 8 t.start()#不代表当前线程会立即被执行 9 t.join(2) #表示主线程到此等待。。。直到子线程执行完成#参数,表示住线程再次最多等待n秒 10 11 print('end') 12 #一秒后显示 13 >>>123 14 >>>end 15 16 import time 17 def f1(arg): 18 time.sleep(1) 19 print(arg) 20 import threading 21 t = threading.Thread(target = f1,args = (123,)) 22 t.setDaemon(True)#表示主线程不等子线程 23 t.start()#不代表当前线程会立即被执行 24 #t.join(2) #表示主线程到此等待。。。直到子线程执行完成#参数,表示住线程再次最多等待n秒 25 26 print('end') 27 #立即显示 28 >>>end
#我们可以写个类继承threading模块的Thead类并加入自定义的构造方法,
#用来添加新功能
class MyThread(threading.Thread):
    def __init__(self,func,args):
        self.func =func
        self.args = args
        #继承父类的构造方法
        super(MyThread,self).__init__()

    def run(self):
        self.func(self.args)

def f2(arg):
    print(arg)

obj = MyThread(f2,123)
obj.start()
>>>123

队列

 

 1 #Python中,队列是线程间最常用的交换数据的形式。Queue模块是提供队列操作的模块,不同的队列应用在不同的场景中
 2 #queue.Queue先进先出队列
 3 #queue.LifoQueue,后进先出队列
 4 #queue.PriorityQueue,优先级队列
 5 #queue.deque,双向队列
 6 
 7 import queue
 8 q = queue.Queue(3)#参数为队列中最大个数
 9 print(q.empty())#判断是否为空
10 >>>True
11 print(q.full())#判断队列是否已满
12 >>>False
13 q.put(11)
14 >>>传入元素
15 q.put(22)
16 >>>传入元素
17 #q.put(33,block=False)#最大值为2传入第三个的时候默认阻塞
18 print(q.qsize())#真实队列剩余个数
19 >>>2
20 print(q.maxsize)#最大个数
21 >>>3
22 print(q.get())#取值当队列中取完之后继续取得时候阻塞
23 >>>11
24 q.task_done()#任务完成
25 print(q.get())#取值
26 >>>22
27 q.task_done()#任务完成,用于释放队列
28 q.join()#不带这个的时候程序完成后释放队列,加上的时候阻塞
 1 #先进后出队列
 2 q = queue.LifoQueue()
 3 q.put(123)
 4 q.put(456)
 5 print(q.get())
 6 #>>>456
 7 
 8 #优先级队列
 9 q = queue.PriorityQueue()
10 q.put((1,'alex1'))
11 q.put((1,'alex2'))
12 q.put((3,'alex3'))
13 print(q.get())
14 >>>(1, 'alex1')
15 
16 
17 #双向队列
18 q= queue.deque()
19 q.append(123)
20 q.append(333)
21 q.appendleft(456)
22 #从左侧插入队列
23 print(q.pop())#从右侧取值
24 print(q.popleft())#从左侧取值
25 >>>333
26 >>>456

生产者消费者模型

#生产者消费者模型
import queue
import threading
import time

#创建队列
q = queue.Queue(50)

#定义消费者
def productor(arg):
    '''
    买票
    :param arg:
    :return:
    '''
    while True:
        q.put(str(arg) + '号产生订单')#提交到队列

#创建300个线程发送请求
for i in range(300):#300个线程同时提交订单相当于300个人同时提交订单
    t = threading.Thread(target= productor,args= (i,))
    t.start()

#定义生产者
def consumer(arg):
    '''
    服务器后台
    :param arg:
    :return:
    '''
    while True:
        print(str(arg) + '处理了'+q.get())#进程从队列中取订单进行处理

#3个线程同时工作
for j in range(3):
    t = threading.Thread(target=consumer,args=(j,))
    t.start()

线程锁 

 

 1 #线程锁
 2 import threading
 3 import time
 4 
 5 NUM = 10
 6 #线程锁线程执行进程通过的接口,用来限制多个线程同时修改一个数据
 7 def func(l):
 8     global NUM
 9     #上锁
10     l.acquire()
11     NUM -=1
12     time.sleep(2)
13     print(NUM)
14     #开锁
15     l.release()
16 #单层锁
17 lock = threading.Lock()
18 #多层锁
19 #lock = threading.RLock()
20 
21 for i in range(30):
22     t  = threading.Thread(target=func,args = (lock,))
23     t.start()

信号量

 1 #设置可通过线程个数
 2 import threading
 3 import time
 4 NUM =10
 5 def func(i,l):
 6     global NUM
 7     #上锁
 8     l.acquire()
 9     NUM -=1
10     time.sleep(2)
11     print(NUM,i)
12     #开锁
13     l.release()
14 
15 #调用信号量设置每次多少个线程处理进程
16 lock = threading.BoundedSemaphore(5)
17 
18 for i in range(30):
19     t = threading.Thread(target= func,args=(i,lock,))
20     t.start()
 1 #event相当于红绿灯,通过一个标识来批量管理线程
 2 import threading
 3 
 4 def func(i,e):
 5     print(i)
 6     e.wait()#检测时什么灯,如果是红灯,停,绿灯,行
 7     print(i+100)
 8 
 9 event = threading.Event()
10 
11 for i in range(10):
12     t = threading.Thread(target= func,args = (i,event,))
13     t.start()
14 
15 event.clear()#设置成红灯
16 inp = input('>>>')
17 if inp == '1':
18     event.set()#设置成绿灯

 

 1 #根据条件限定线程的执行
 2 #!/usr/bin/env python
 3 # -*- coding:utf-8 -*-
 4 #设置条件设置线程数第一种方式
 5 import threading
 6 def func(i,con):
 7     print(i)
 8     con.acquire()
 9     con.wait()
10     print(i+100)
11     con.release()
12 
13 c = threading.Condition()
14 for i in range(10):
15     t = threading.Thread(target=func,args=(i,c))
16     t.start()
17 
18 while True:
19     inp = input('>>>')
20     if inp == 'q':
21         break
22     c.acquire()
23     c.notify(int(inp))#根据输入设置通过几个线程数
24     c.release()
25 
26 #第二种
27 import threading
28 
29 def condition():
30     ret =False
31     r = input('>>>')
32     if r == 'true':
33         ret =True
34     else:
35         ret = False
36     return ret
37 
38 def func(i,con):
39     print(i)
40     con.acquire()
41     # 设置condition函数为条件返回true继续运行,条件不成立则不执行此线程
42     con.wait_for(condition)
43     print(i+100)
44     con.release()
45 
46 c = threading.Condition()
47 for i in range(10):
48     t = threading.Thread(target=func,args=(i,c))
49     t.start()

Timer

1 #定时器
2 form threading import Time
3 
4 def hello():
5     print('hello')
6 t = Timer(1,hello)#一秒后执行
7 t.start()

线程池

 1 import queue
 2 import threading
 3 import time
 4 
 5 class ThreadPool:
 6     def __init__(self,maxsize):
 7         self.maxsize = maxsize
 8         self._q = queue.Queue(maxsize)#创建队列
 9         for i in range(maxsize):
10             self._q.put(threading.Thread)#将创建线程的类放入队列
11 
12     def get_thread(self):
13         return self._q.get()#获取队列的值
14 
15     def add_thread(self):
16         self._q.put(threading.Thread)
17 
18 pool = ThreadPool(5)#设置线程池
19 def task(arg,p):
20     print(arg)
21     time.sleep(1)
22     p.add_thread()#添加新的线程
23 
24 for i in range(100):
25     t = pool.get_thread()#当获取5次后,阻塞在此
26     obj = t(target = task,args = (i,pool,))#创建线程调用函数task
27     obj.start()
  1 #第二种创建线程池方式
  2 #!/usr/bin/env python
  3 # -*- coding:utf-8 -*-
  4 
  5 
  6 import queue
  7 import threading
  8 import contextlib
  9 import time
 10 
 11 StopEvent = object()
 12 class Pool:
 13     def __init__(self,max_num,max_task_num=None):
 14         if max_task_num:
 15             self.q=queue.Queue(max_task_num)#创建队列并指定接受任务最大数
 16         else:
 17             self.q = queue.Queue()#不指定参数
 18         self.max_num = max_num#最多有多少个线程
 19         self.cancel = False
 20         self.terminal = False
 21         self.generate_list = []#已创建线程
 22         self.free_list = []#空闲线程
 23 
 24     def run(self,func,args,callback = None):#接收参数
 25         if self.cancel:
 26             return
 27         if len(self.free_list) ==0 and len(self.generate_list) < self.max_num:#当没有空闲线程并且,已创建的线程没有达到最大值
 28             self.generate_thread() #创建新线程调generte_thread函数
 29         w = (func,args,callback,)#将参数传入队列中
 30         self.q.put(w)#将参数作为元组传入队列中
 31 
 32     def generate_thread(self):
 33         '''
 34         创建线程
 35         :return:
 36         '''
 37         t = threading.Thread(target=self.call)#执行call函数
 38         t.start()
 39     def call(self):
 40         '''
 41         让线程执行任务
 42         :return:
 43         '''
 44         current_thread = threading.currentThread#获取当前线程数
 45         self.generate_list.append(current_thread)#传入已创建线程列表中
 46         event =self.q.get()#获取任务
 47         while event != StopEvent:#如果任务不为空
 48             func,args,callback = event#将传过来的参数赋值给event
 49             try:
 50                 result = func(args)#执行action(i)
 51                 success = True#任务执行成功
 52             except Exception as e:
 53                 success = False#action任务执行失败
 54             if callback is not None:
 55                 try:
 56                     callback(success,result)
 57                 except Exception as c:
 58                     pass
 59             #event.self.q.get()#继续去任务,当存在任务则执行action不存在则删除当前进程
 60                 with self.worker_state(self.free_list,current_thread):#任务执行完成后设置该线程为空闲
 61                     if self.terminal:#如果是空闲的
 62                         event = StopEvent
 63                     else:
 64                         event = self.q.get()#如果不是空闲的,则去取任务
 65         else:
 66             self.generate_list.remove(current_thread)#如果任务为空则删除当前线程
 67 
 68     def close(self):
 69         '''
 70         执行完所有任务后,所有线程停止
 71         :return:
 72         '''
 73         self.cancel = True
 74         full_size = len(self.generate_list)#统计线程个数
 75         while full_size:#根据线程个数传入对应个数的False标志
 76             self.q.put(StopEvent)
 77             full_size -=1
 78 
 79     def terminate(self):
 80         """
 81         无论是否还有任务,终止线程
 82         """
 83         self.terminal = True
 84 
 85         while self.generate_list:
 86             self.q.put(StopEvent)
 87         self.q.empty()
 88 
 89 
 90     @contextlib.contextmanager
 91     def worker_state(self, state_list, worker_thread):
 92         """
 93         用于记录线程中正在等待的线程数
 94         """
 95         state_list.append(worker_thread)
 96         try:
 97             yield
 98         finally:
 99             state_list.remove(worker_thread)
100 pool = Pool(5)
101 
102 def action():
103     pass
104 def callback(i):
105     print(i)
106 for i in range(300):
107     ret = pool.run(action,(i,),callback)#将函数i的值与callback函数传入类中

 

posted @ 2016-07-19 22:44  ppppppy  阅读(413)  评论(0编辑  收藏  举报