• 【python自动化第十篇:】


    复习:

      线程与进程的区别:

        进程:资源的集合

        线程:最小调度单位

    • 进程至少包含一个线程
      • 线程之间的内存是共享的,两个线程操作同一个数据就会修改整个结果(需要mutex加锁来保持数据的一致性),递归锁,join(等待线程执行完成)

               信号量:也相当于是lock

        守护线程:服务于非守护线程;

        quene:程序的解耦;提高效率;也是有序的容器;队列只有一份数据,取完了就没有了

            先进先出(FIFO)

            后进先出(LIFO)

        生产者消费者模型:也就是为了实现解耦

        event:事件---红绿灯实验

    i/o不占用cpu,计算占用

    python多线程不适合cpu密集型操作任务,适合i/o密集型任务

    推荐的书:

      《失控》,《必然》

      《数学之美》,《浪潮之巅》

    鸡汤总结:做一个有素质的人

    今天的课程:

    1. govent协程
    2. selectpollepoll异步I/O事件驱动
    3. python连接mysql的基本操作
    4. rabbitmq队列
    5. redis/memcached缓存
    6. paramiko ssh
    7. twisted网络框架

    一、多进程

      解决多核问题而生

    单个进程:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import multiprocessing,time
    def run(name):                      #定义函数
        time.sleep(1)
        print('hello',name)                        
    if __name__ == '__main__':    
        p = multiprocessing.Process(target=run,args=('hehe',))        #实例化一个进程
        p.start()                                                      #执行进程
        p.join()                                                       #进程等待
    

    多进程:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import multiprocessing,time
    
    def run(name):
        print('hello',name)
        time.sleep(1)
    if __name__ == '__main__':
        for i in range(10):          #定义循环
            p = multiprocessing.Process(target=run,args=("hehe %s"%i,))
            p.start()
    

    获取进程id:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import multiprocessing,os
    
    def info(title):                  #信息展示函数
        print(title)
        print('module name:',__name__) #打印模块名称
        print('parent process id',os.getppid()) #父进程id获取
        print('process id',os.getpid())     #当前进程id
        print('
    
    ')
    
    def f(name):                               #定义功能函数
        info('33[31;1mfunction f33[0m')
        print('hello',name)
    
    if __name__ == '__main__':                  #主进程调用
        info('33[32;1mmain process line33[0m')
        p = multiprocessing.Process(target=f,args=('hehe',))     #定义进程
        p.start()                                                 #开始进程
        p.join()                                                  #进程等待
    

    每一个子进程都是有其父进程启动的

    进程间通信:Queue

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from multiprocessing import Queue,Process
    
    def f(qq):
        qq.put([122,None,'heheheda'])        #父进程放入数据
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f,args=(q,))       #将q传给子进程p
        p.start()
        print(q.get())
        p.join()
    

      此时的q也就是pickle序列化和 反序列化之后的结果了,实现了进程间的通信

    管道pipe:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from multiprocessing import Process,Pipe
    
    def f(conn):
        conn.send([123,'sada',None])      #子进程send数据
        conn.send([12223,'s343ada321',None])      #子进程send数据
        print(conn.recv())                     #子进程接受父进程数据
        conn.close()
    
    if __name__ == '__main__':
        parent_conn,chile_conn = Pipe()      #生成一个管道实例
        p = Process(target=f,args=(chile_conn,))  #实例化
        p.start()
        print(parent_conn.recv())              #父进程接收数据
        print(parent_conn.recv())              #父进程接收数据
       # print(parent_conn.recv())              #父进程接收数据,如果子进程不发送数据,父进程就处于等待状态
        parent_conn.send('hello child!!')   #父进程给子进程发送数据
        p.join()
    

    mananger:实现进程间数据共享 

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #Author:wanghui
    from multiprocessing import Manager,Process
    import os
    def f(d,l):
        d[os.getpid()] = os.getpid()    #获取pid
        l.append(os.getpid())
        print(l)
    if __name__ == '__main__':
        with Manager() as manager:
            d = manager.dict()          #生成一个字典,可在多个进程间共享和传递
            l = manager.list(range(5))    #生成一个列表,可在多个进程间共享和传递数据
            p_list = []
            for i in range(5):
                p = Process(target=f,args=(d,l))
                p.start()
                p_list.append(p)
            for res in p_list:            #等待结果
                res.join()
            print(d)
            print(l)
    

      结果如下:

    D:pythom35python.exe D:/project/s14/day10/manager2.py
    [0, 1, 2, 3, 4, 7828]
    [0, 1, 2, 3, 4, 7828, 4180]
    [0, 1, 2, 3, 4, 7828, 4180, 1800]
    [0, 1, 2, 3, 4, 7828, 4180, 1800, 8076]
    [0, 1, 2, 3, 4, 7828, 4180, 1800, 8076, 7264]
    {1800: 1800, 4180: 4180, 8076: 8076, 7828: 7828, 7264: 7264}     #进程字典打印结果
    [0, 1, 2, 3, 4, 7828, 4180, 1800, 8076, 7264]
    

    进程锁:实现进程同步

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from multiprocessing import Process,Lock
    def f(l,i):
        '''
        :param l: 锁
        :param i: 传进来的内容
        :return:
        '''
       # l.acquire()
        print('hehehe',i)
        #l.release()
    if __name__ == '__main__':
        lock = Lock()
        for num in range(100):             #修改进程的启动数量
            Process(target=f,args=(lock,num)).start()       #启动进程
     
    

    进程池:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from multiprocessing import Process,Pool
    import time,os
    def Foo(i):
        time.sleep(1)
        print('in process',os.getpid())
        return i + 100
    def Bar(arg):
        print("-->exec done",arg,os.getpid())             #获取子进程pid
    if __name__ == '__main__':
        pool = Pool(5)        #允许进程池里同时放入5个进程
        print('主进程',os.getpid())             #获取主进程pid
        for i in range(10):      #启动10个进程
            pool.apply_async(func=Foo,args=(i,),callback=Bar)       #异步执行(并行),需要执行join ,callback:回调
            #pool.apply(func=Foo,args=(i,))            #将Foo放入进程池,串行
        print('end')
        pool.close()
        pool.join()    #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()
    

    二、协程

      又名微线程,轻量级线程;

      协程拥有自己的寄存器上下文和栈;协程

      

        

  • 相关阅读:
    Trie图
    Bestcoder Round#45
    Codeforces Round#308
    bestcoder44#1002
    LCA最近公共祖先 Tarjan离线算法
    HYSBZ 1269文本编辑器 splay
    NOI2005维修数列 splay
    hdu3487 伸展树(区间搬移 区间旋转)
    poj3580 伸展树(区间翻转 区间搬移 删除结点 加入结点 成段更新)
    hdu1890 伸展树(区间反转)
  • 原文地址:https://www.cnblogs.com/wanghui1991/p/5910332.html
Copyright © 2020-2023  润新知