zoukankan      html  css  js  c++  java
  • day 34 编程之补充内容

    生产消费者模型(必须要理解并且牢记,默写内容):

    from multiprocessing import Process,Queue
    import time,random,os
    
    def procducer(q):
        for i in range(10):
            res='包子%s' %i
            time.sleep(0.5)
            q.put(res)
            print('%s 生产了 %s' %(os.getpid(),res))
    
    def consumer(q):
        while True:
            res=q.get()
            if res is None:
                break
            print('%s 吃 %s' %(os.getpid(),res))
            time.sleep(random.randint(2,3))
    
    
    if __name__ == '__main__':
        q=Queue()
        p=Process(target=procducer,args=(q,))
        c=Process(target=consumer,args=(q,))
    
        p.start()
        c.start()
    
        p.join()
        q.put(None)
        print('')
    View Code

    今日概要:

    1 守护进程vs守护线程(*

    2 互斥锁(**

    3 信号量(**

    4 生产者消费者模型(*****

    5 GIL(什么时候用进程,什么时候用线程)(*****) ===========>这里明天讲

     

    守护进程和守护线程:

    # #守护进程
    # from multiprocessing import Process
    # import os,time,random
    #
    # def task():
    #     print('%s is running' %os.getpid())
    #     time.sleep(2)
    #     print('%s is done' %os.getpid())
    #     # p = Process(target=time.sleep, args=(3,))
    #     # p.start()
    #
    # if __name__ == '__main__':
    #     p=Process(target=task)
    #     p.daemon = True #1、必须在p.start()之前 2:守护进程不能开启子进程
    #     p.start()
    #     # p.join()
    #     print('主')
    #
    #     '''
    #     举例说明守护进程的应用场景:
    #         假设有两个任务要干,要玩出并发的效果,使用进程的话可以让主进程
    #         执行一个任务,然后开启一个子进程执行一个任务。
    #
    #         如果这两个任务毫无关系,那么就像上面这么做就可以
    #         如果主进程的任务在执行完毕后,子进程的任务没有存在的意义了
    #         那么该子进程应该在开启之前就被设置成守护进程
    #     '''
    
    
    #迷惑人的例子
    #主进程代码运行完毕,守护进程就会结束
    # from multiprocessing import Process
    # from threading import Thread
    # import time
    # def foo():
    #     print(123)
    #     time.sleep(1)
    #     print("end123")
    #
    # def bar():
    #     print(456)
    #     time.sleep(3)
    #     print("end456")
    #
    # if __name__ == '__main__':
    #     p1=Process(target=foo)
    #     p2 = Process(target=bar)
    #
    #     p1.daemon=True
    #     p1.start()
    #     p2.start()
    #     print("main-------") #打印该行则主进程代码结束,则守护进程p1应该被终止,可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止
    #
    
    
    
    
    
    # # #守护线程:等到该进程内所有非守护线程都运行完才死掉
    # from multiprocessing import Process
    # from threading import Thread
    # import os,time,random
    #
    # def task():
    #     # t=Thread(target=time.sleep,args=(3,))
    #     # t.start()
    #     print('%s is running' %os.getpid())
    #     time.sleep(2)
    #     print('%s is done' %os.getpid())
    #
    # if __name__ == '__main__':
    #     t=Thread(target=task)
    #     t.daemon = True #1、必须在t.start()之前
    #     t.start()
    #     # t.join()
    #     print('主')
    
    
    #迷惑人的例子
    #主进程代码运行完毕,守护进程就会结束
    from multiprocessing import Process
    from threading import Thread
    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-------")
    
    '''
    123
    456
    main-------
    end123
    end456
    '''
    View Code

    理解补充:

    这里的的意思就是:我们要开启守护进程,开启的方式要在start之前开启,然后用固定格式开启,
    # 开启之后的结果就是,守护进程是等待主进程执行完了自己的代码之后就会挂掉,至于主进程里面的其他的子进程就不考虑了,
    # 即便那些子进程还没有执行完成我们也不会去继续执行了,程序到主进程执行完成后就结束了,这里就是守护进程的作用.
    # 至于他的应用场景,就是在实现并发的情况下,我们在主进程里面需要开启其他的进程来帮助我们执行任务,这些任务彼此之间是有关联的,
    # 我们只需要在主进程执行完后就不需要其他的子进程继续去执行了,
    这个时候我们的子进程就需要被设置为守护进程



    互斥锁--------进程:
    from multiprocessing import Process,Lock
    import os,time,random
    
    def task(mutex):
        mutex.acquire()
        print('%s print 1' %os.getpid())
        time.sleep(random.randint(1,3))
        print('%s print 2' %os.getpid())
        time.sleep(random.randint(1, 3))
        print('%s print 3' %os.getpid())
        mutex.release()
    
    if __name__ == '__main__':
        # p1=Process(target=task)
        # p2=Process(target=task)
        # p3=Process(target=task)
        # p1.start()
        # p1.join()
        # p2.start()
        # p2.join()
        # p3.start()
        # p3.join()
    
        mutex=Lock()
        p1=Process(target=task,args=(mutex,))
        p2=Process(target=task,args=(mutex,))
        p3=Process(target=task,args=(mutex,))
        p1.start()
        p2.start()
        p3.start()
    View Code
    
    

    锁进程的时候,当主进程执行完毕后,守护进程立即挂掉,即便此时还有没有执行完了子进程也不会去执行了,整个程序立即结束

    互斥锁-------------线程:

    from threading import Thread,Lock
    import time
    n=100
    
    def task():
        # global n
        # mutex.acquire()
        # temp=n
        # time.sleep(0.1)
        # n=temp-1
        # mutex.release()
    
        global n
        with mutex:
            temp=n
            time.sleep(0.1)
            n=temp-1
    
    
    
    if __name__ == '__main__':
        mutex=Lock()
        t_l=[]
        for i in range(100):
            t=Thread(target=task)
            t_l.append(t)
            t.start()
    
        for t in t_l:
            t.join()
    
        print(n)
    View Code

    线程里面有两种情况,如果主线程执行完了此时守护线程还没有完,就会立即挂掉,但是,如果主线程已经完了,守护线程还没有完,那么它作为守护线程也会挂掉.

    这里有一个例子,可以加深对于锁的理解:

    from multiprocessing import Process,Lock
    import json
    import os
    import time
    import random
    
    # import json
    # with open('db.txt','w',encoding='utf-8') as f:
    #     json.dump({'count':1},f)
    # 在程序运行前先运行一下这上面的三行代码
    def search():
        with open('db.txt',encoding='utf-8') as f:
            dic=json.load(f)
            print('%s 剩余票数 %s' %(os.getpid(),dic['count']))
    
    def get():
        with open('db.txt',encoding='utf-8') as read_f:
            dic=json.load(read_f)
    
        if dic['count'] > 0:
            dic['count']-=1
            time.sleep(random.randint(1,3)) #模拟手速+网速
            with open('db.txt','w',encoding='utf-8') as write_f:
                json.dump(dic,write_f)
                print('%s 抢票成功' %os.getpid())
    
    def task(mutex):
        search()
        mutex.acquire()
        get()
        mutex.release()
    
    if __name__ == '__main__':
        # for i in range(20):
        #     p=Process(target=task)
        #     p.start()
        #     p.join()
    
        mutex = Lock()
        for i in range(10):
            p = Process(target=task, args=(mutex, ))
            p.start()
    View Code

    信号量(理解即可,不必深究):

    from multiprocessing import Process,Semaphore
    # from threading import Thread,Semaphore
    import time,random,os
    
    def task(sm):
        with sm:
            print('%s 上厕所' %os.getpid())
            time.sleep(random.randint(1,3))
    
    
    if __name__ == '__main__':
        sm=Semaphore(3)
        for i in range(10):
            p=Process(target=task,args=(sm,))
            p.start()
    
    
    # 这里是信号量,它跟进程池就是多了一个锁的概念,资源抢占,相当于是在一个公司里有很多# 人要干活,
    # 每个人的分工不同,大家平日里都是各做各的事情,但是大家都会牵扯到使用打印机的情况,当大家都扎堆使用打印机的时候,
    # 这里就牵扯到了信号量的概念,打印机只有3个,但是使用它的人却源源不断理解到这即可
    View Code

    队列,堆栈,优先级:

    from multiprocessing import Queue #进程队列
    
    # q=Queue(3)
    #
    # q.put({'a':1})
    # q.put('xxxxx')
    # q.put(3)
    # q.put(4)
    
    
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())
    
    
    
    import queue #线程队列
    
    #队列
    # q=queue.Queue(3)
    # q.put({'a':1})
    # q.put('xxxxx')
    # q.put(3)
    # q.put(4)
    
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())
    
    #优先级队列
    # q=queue.PriorityQueue(3)
    # q.put((10,{'a':1}))
    # q.put((-1,'xxxxx'))
    # q.put((0,3))
    # # q.put(4)
    #
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())
    
    
    
    #堆栈
    # q=queue.LifoQueue(3)
    # q.put({'a':1})
    # q.put('xxxxx')
    # q.put(3)
    # # q.put(4)
    #
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())
    View Code
     
    # #pip install requests
    # import requests
    # from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    # from threading import current_thread
    # import time
    # import os
    #
    # def get(url):
    # print('%s GET %s' %(os.getpid(),url))
    # response=requests.get(url)
    # time.sleep(3)
    # if response.status_code == 200:
    # return {'url':url,'text':response.text}
    #
    # def parse(obj):
    # res=obj.result()
    # print('[%s] <%s> (%s)' % (os.getpid(), res['url'],len(res['text'])))
    #
    # if __name__ == '__main__':
    # urls = [
    # 'https://www.python.org',
    # 'https://www.baidu.com',
    # 'https://www.jd.com',
    # 'https://www.tmall.com',
    # ]
    # # t=ThreadPoolExecutor(2)
    # t=ProcessPoolExecutor(2)
    # for url in urls:
    # t.submit(get,url).add_done_callback(parse)
    # t.shutdown(wait=True)
    #
    # print('',os.getpid())

    # '''
    # 异步调用:
    # 提交完任务(为该任务绑定一个回调函数),不用再原地等任务执行完毕拿到结果,可以直接提交下一个任务
    # 一个任务一旦执行完毕就会自动触发回调函数的运行
    #
    # 回调函数的参数是单一的:
    # 回调函数的参数就是它所绑定任务的返回值
    #
    # '''


    #pip install requests

    import requests
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    from threading import current_thread
    import time
    import os

    def get(url):
    print('%s GET %s' %(current_thread().getName(),url))
    response=requests.get(url)
    time.sleep(3)
    if response.status_code == 200:
    return {'url':url,'text':response.text}

    def parse(obj):
    res=obj.result()
    print('[%s] <%s> (%s)' % (current_thread().getName(), res['url'],len(res['text'])))

    if __name__ == '__main__':
    urls = [
    'https://www.python.org',
    'https://www.baidu.com',
    'https://www.jd.com',
    'https://www.tmall.com',
    ]
    t=ThreadPoolExecutor(2)
    for url in urls:
    t.submit(get,url).add_done_callback(parse)
    t.shutdown(wait=True)

    print('',os.getpid())
  • 相关阅读:
    关于微服务的协议概述
    Eclipse 安装阿里巴巴代码规范插件
    Eclipse安装LomBok插件
    关于JAVA架构师
    关于Object类的一些方法
    [SoapUI] SoapUI官方文档
    [Jmeter] 用xsltproc生成html格式的报告
    [RF] Robot Framework新手干货(转载)
    【SoapUI】比较Json response
    怎样查看一个端口有无开启
  • 原文地址:https://www.cnblogs.com/2012-dream/p/7979555.html
Copyright © 2011-2022 走看看