• 并发编程(二)


    并发编程(二)    >>>思维导图>>>中二青年

    队列

    队列:先进先出

    堆栈:先进后出

    q = Queue(5) 括号内可以传参数:表示的是这个队列的最大存储数

    q.put(1) 括号内可以传参数:表示往队列中添加数据,当对列满了,程序会阻塞,直到有人从队列中取走值

    q.get():表示向队列取值,当取完后再次获取,程序会阻塞,直到有人往队列存入值

    q.full():判断对列是否满了

    q.empty():判断队列中的数据是否取完

    q.get_nowait():取值,没有值不等待直接报错

    full,get_nowait,empty都不适用与多进程的情况

    其他方法

    q.qsize() 
        返回队列中目前项目的正确数量。此函数的结果并不可靠,因为在返回结果和在稍后程序中使用结果之间,队列中可能添加或删除了项目。在某些系统上,此方法可能引发NotImplementedError异常。
    q.close() 
        关闭队列,防止队列中加入更多数据。调用此方法时,后台线程将继续写入那些已入队列但尚未写入的数据,但将在此方法完成时马上关闭。如果q被垃圾收集,将自动调用此方法。关闭队列不会在队列使用者中生成任何类型的数据结束信号或异常。例如,如果某个使用者正被阻塞在get()操作上,关闭生产者中的队列不会导致get()方法返回错误。
    q.cancel_join_thread()
        不会再进程退出时自动连接后台线程。这可以防止join_thread()方法阻塞。
    q.join_thread() 
        连接队列的后台线程。此方法用于在调用q.close()方法后,等待所有队列项被消耗。默认情况下,此方法由不是q的原始创建者的所有进程调用。调用q.cancel_join_thread()方法可以禁止这种行为。
    View Code

    进程间的通信IPC机制

    子进程放数据,主进程获取数据

    两个子进程相互放,取数据

    from multiprocessing import Process,Queue
    def producer(q):
        q.put('hello GF~')
    def consumer(q):
        print(q.get())
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=producer,args=(q,))
        c = Process(target=consumer, args=(q,))
        p.start()
        c.start()
    View Code

    生产者消费者模型

    生产者:生产/制造数据的

    消费者:消费/处理数据的

    例子:做包子的,买包子的

    # 1.做包子远比买包子的多
    # 2.做包子的远比包子的少
    # 供需不平衡的问题
    from multiprocessing import Process,Queue,JoinableQueue
    import random
    import time
    def producer(name,food,q):
        for i in range(10):
            data = '%s生产了%s%s'%(name,food,i)
            time.sleep(random.random())
            q.put(data)
            print(data)
    def consumer(name,q):
        while True:
            data = q.get()
            if data == None:break
            print('%s吃了%s'%(name,data))
            time.sleep(random.random())
            q.task_done()  # 告诉队列你已经从队列中取出了一个数据 并且处理完毕了
    if __name__ == '__main__':
        q = JoinableQueue()
        p = Process(target=producer,args=('大厨egon','馒头',q))
        p1 = Process(target=producer,args=('跟班tank','生蚝',q))
        c = Process(target=consumer,args=('许兆龙',q))
        c1 = Process(target=consumer,args=('吃货jerry',q))
        p.start()
        p1.start()
        c.daemon = True
        c1.daemon = True
        c.start()
        c1.start()
        p.join()
        p1.join()
        q.join()  # 等到队列中数据全部取出
        # q.put(None)
        # q.put(None)
    View Code

    线程

    进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物

    进程:资源单位

    线程:执行单位

    将内存比如成工厂那么进程就相当于是工厂里面的车间而你的线程就相当于是车间里面的流水线ps:每个进程都自带一个线程,线程才是真正的执行单位,进程只是在线程运行过程中提供代码运行所需要的资源

    开进程
    1.申请内存空间  耗资源2."拷贝代码"    耗资源

    开线程
    一个进程内可以起多个线程,并且线程与线程之间数据是共享的ps:开启线程的开销要远远小于开启进程的开销

    创建进程的两种方式

    from threading import Thread
    import time
    def task(name):
        print('%s is running'%name)
        time.sleep(3)
        print('%s is over'%name)
    # 开线程不需要在__main__代码块内     但是习惯性的还是写在__main__代码块内
    t = Thread(target=task,args=('egon',))
    t.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
    # 小的代码执行完 线程就已经开启了
    print('')
    方式一
    from threading import Thread
    import time
    class MyThread(Thread):
        def __init__(self,name):
            super().__init__()
            self.name = name
        def run(self):
            print('%s is running'%self.name)
            time.sleep(3)
            print('%s is over'%self.name)
    t = MyThread('egon')
    t.start()
    print('')
    方式二

    线程对象及其他方法

    from threading import Thread,current_thread,active_count
    import time
    import os
    def task(name,i):
        print('%s is running'%name)
        # print('子current_thread:',current_thread().name)
        # print('子',os.getpid())
        time.sleep(i)
        print('%s is over'%name)
    # 开线程不需要在__main__代码块内 但是习惯性的还是写在__main__代码块内
    t = Thread(target=task,args=('egon',1))
    t1 = Thread(target=task,args=('jason',2))
    t.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
    t1.start()  # 告诉操作系统开辟一个线程  线程的开销远远小于进程
    t1.join()  # 主线程等待子线程运行完毕
    print('当前正在活跃的线程数',active_count())
    # 小的代码执行完 线程就已经开启了
    print('')
    # print('主current_thread:',current_thread().name)
    # print('主',os.getpid())
    View Code

    threading模块

    multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性

    Thread类的其他方法

    Thread实例对象的方法
      # isAlive(): 返回线程是否活动的。
      # getName(): 返回线程名。
      # setName(): 设置线程名。
    threading模块提供的一些方法:
      # threading.currentThread(): 返回当前的线程变量。
      # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
      # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

    join方法

    from threading import Thread
    import time
    def sayhi(name):
        time.sleep(2)
        print('%s say hello' %name)
    if __name__ == '__main__':
        t=Thread(target=sayhi,args=('egon',))
        t.start()
        t.join()
        print('主线程')
        print(t.is_alive())
        '''
        egon say hello
        主线程
        False
        '''
    View Code

    守护线程

    主线程的结束也就意味着进程的结束

    主线程必须等待其他非守护线程的结束才能结束
    (意味子线程在运行的时候需要使用进程中的资源,而主线程一旦结束了资源也就销毁了)

    from threading import Thread,current_thread
    import time
    def task(i):
        print(current_thread().name)
        time.sleep(i)
        print('GG')
    # for i in range(3):
    #     t = Thread(target=task,args=(i,))
    #     t.start()
    t = Thread(target=task,args=(1,))
    t.daemon = True
    t.start()
    print('')

    线程间通信

    from threading import Thread
    money = 666
    def task():
        global money
        money = 999
    t = Thread(target=task)
    t.start()
    t.join()
    print(money)

    互斥锁

    from threading import Thread,Lock
    import time
    n = 100
    def task(mutex):
        global  n
        mutex.acquire()
        tmp = n
        time.sleep(0.1)
        n = tmp - 1
        mutex.release()
    t_list = []
    mutex = Lock()
    for i in range(100):
        t = Thread(target=task,args=(mutex,))
        t.start()
        t_list.append(t)
    for t in t_list:
        t.join()
    print(n)

    小例子

    from threading import Thread
    from multiprocessing import Process
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    if __name__ == '__main__':
        t1=Thread(target=foo)
        t2=Thread(target=bar)
        t1.daemon=True
        t1.start()
        t2.start()
        print("main-------")
    View Code

    END

  • 相关阅读:
    神舟笔记本反厂后带来的惊喜与郁闷
    如今是否还要坚持asp.net,坚持程序员这个不怎么光荣的称号
    严援朝的一句名言
    一个专科生程序员的痛苦境遇
    overflow:hidden 文本不在over 范围,也不显示
    困扰很久的问题
    未来已来,4K激活字库产业新世代
    4K超高清,为字库产业,打开了数字家电的大门
    2012中文字库简单统计与分类
    图说字王数格纵系列
  • 原文地址:https://www.cnblogs.com/renvip/p/11340425.html
Copyright © 2020-2023  润新知