zoukankan      html  css  js  c++  java
  • 并发编程

    并发编程

    守护进程

    若a为b的守护进程,a进程结束,b进程未结束,则会等待进程结束后结束整体进程;

    ​ b进程结束,a进程未结束,则会立即结束整体进程

    Process.daemon = True  
    
    from multiprocessing import Process
    import time
    
    def task():
        print('zi run')
        time.sleep(3)
        print('zi over')
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.daemon = True           # 将这个进程设置为了守护进程
        p.start()
        time.sleep(4)
    
        print('zhu over')
    

    进程安全问题

    当并发的多个任务要同时操作公共资源时,就是造成数据错乱的问题

    解决方法就是讲并发操作编程串行操作,但是牺牲了效率,提升了安全性

    1. 将并行改成串行
    2. 互斥锁

    互斥锁

    互斥锁是为了让公共内容有序进行

    互斥锁内的内容是串行,锁外面的内容还可以是并发

    from multiprocessing import Lock
    
    from multiprocessing import Process,Lock
    import time,random
    
    def task1(mutex):
        for i in range(10000):   # 锁外面的内容还是可以实现并发
            print(1)
        mutex.acquire()          # 加锁
        print('zi1 run')
        time.sleep(3)
        print('zi1 over')
        mutex.release()         # 解锁
    
    def task2(mutex):
        for i in range(10000):
            print(2)
        mutex.acquire()        # 加锁
        print('zi2 run')
        time.sleep(3)
        print('zi2 over')
        mutex.release()      # 解锁
    
    if __name__ == '__main__':
        mutex = Lock()        # 创建锁
        p1 = Process(target=task1,args=(mutex,))
        p2 = Process(target=task2, args=(mutex,))
        p1.start()
        p2.start()
    

    Manager的使用

    from multiprocessing import Process,Manager,Lock
    import time
    
    def task(data,lock):
        lock.acquire()
        num = data[0]
        time.sleep(0.2)
        data[0] = num - 1
        lock.release()
    
        print("子 over")
    
    
    if __name__ == '__main__':
    
        d = [100]
        m = Manager() # 创建一个管理器
        syncdict = m.list(d) # 让管理器创建一个进程同步的字典
    
        # 创建一个锁
        lock = Lock()
    
        ps = []
        for i in range(10):
            p = Process(target=task,args=(syncdict,lock))
            p.start()
            ps.append(p)
    

    进程队列

    队列 先进先出

    from multiprocessing import Queue
    
    q = Queue(2) # 创建队列 并且同时只能存储2个元素
    q.put(1)
    q.put(2)
    
    # q.put(3,block=True,timeout=3) # 默认是阻塞的 当容器中没有位置了就阻塞 直到有人从里面取走元素为止
    
    
    print(q.get())
    print(q.get())
    print(q.get(block=True,timeout=3))# 默认是阻塞的 当容器中没有位置了就阻塞 直到有人存入元素为止
    

    函数调用栈

    通过函数调用函数

    ​ 最先执行的函数反而是最后结束的,最后执行的函数是最先结束的

    def a():
        b()
    
    
    def b():
        c()
    
    
    def c():
        print('c')
        raise  Exception
    
    
    a()
    

    进程间通信几种方式

    1. 创建一个共享文件

      ​ 缺点:效率低

      ​ 优点:理论上交换的数据量非常大

      ​ 适用于:交互不频繁但是数据量非常大的情况

    2. 共享内存

      ​ 缺点:数据量不能太大

      ​ 优点:效率高

      ​ 适用于:交互频繁,数据量较小

    3. 管道

      ​ 管道也是基于文件的,它是单向的,编程比较复杂

    4. socket

      ​ 编程复杂,更适用于基于网络来交换数据

  • 相关阅读:
    js设置奇偶行数样式
    c#简单的调试信息、日志信息输出
    调用接口
    sql日期转换格式
    .net 常用方法
    日常验证
    Js 返回页面 or 跳转页面
    .NET Core Kestrel部署HTTPS以及Docker部署HTTPS
    Linux openssl生成证书
    ASP.NET Core中使用AutoMapper实现自动转化
  • 原文地址:https://www.cnblogs.com/einsam/p/11157550.html
Copyright © 2011-2022 走看看