生产者与消费者:解决多任务中数据缓存的问题,能够解耦
解决数据生产方和数据处理方的数据缓存问题
#encoding=utf-8
import threading
import time
#python2中
from Queue import Queue
#python3中
# from queue import Queue
class Producer(threading.Thread):
def run(self):
global queue
count = 0
while True:
if queue.qsize() < 1000:
for i in range(100):
count = count +1
msg = '生成产品'+str(count)
queue.put(msg)
print(msg)
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global queue
while True:
if queue.qsize() > 100:
for i in range(3):
msg = self.name + '消费了 '+queue.get()
print(msg)
time.sleep(1)
if __name__ == '__main__':
queue = Queue()
for i in range(500):
queue.put('初始产品'+str(i))
for i in range(2):
p = Producer()
p.start()
for i in range(5):
c = Consumer()
c.start()
ThreadLocal
函数之间参数传递:1、传参 2、全局
得到一个函数的结果:1、return 2、放到全局变量中去
在线程中只能传递,不能全局变量,因为全局变量在线程中会相互影响。
import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student()
t1 = threading.Thread(target= process_thread, args=('dongGe',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('老王',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
执行结果:
Hello, dongGe (in Thread-A)
Hello, 老王 (in Thread-B)
一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题
思考:threading.local()创建出来的变量非常特殊,能够记录各自线程写入的数据。
image.png
异步
正在做一件事,但不确定什么时候会被打断去做另一件事
异步的好处,可以提高效率,节省时间
from multiprocessing import Pool
import time
import os
def test():
print("---进程池中的进程---pid=%d,ppid=%d--"%(os.getpid(),os.getppid()))
for i in range(3):
print("----%d---"%i)
time.sleep(1)
return "hahah"
def test2(args):
print("---callback func--pid=%d"%os.getpid())
print("---callback func--args=%s"%args)
pool = Pool(3)
pool.apply_async(func=test,callback=test2)
time.sleep(5)
print("----主进程-pid=%d----"%os.getpid())
运行结果:
---进程池中的进程---pid=9401,ppid=9400--
----0---
----1---
----2---
---callback func--pid=9400
---callback func--args=hahah
----主进程-pid=9400----
GIL的问题——全局解释器锁
Python中的线程是假的,当核数多的时候,进程比线程运行效率更高
可以用粘贴C语言的方式,解决Python的GIL问题
image.png