2018-04-17生产者与消费者模式、ThreadLocal、异步、GIL

生产者与消费者:解决多任务中数据缓存的问题,能够解耦
解决数据生产方和数据处理方的数据缓存问题

#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

你可能感兴趣的:(2018-04-17生产者与消费者模式、ThreadLocal、异步、GIL)