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

      并发编程,并发就是从主观上看起来运行多个进程,是在用单核CUP经行处理是使用。并行与之相比,就是客观在同一时间段,处理不同程序。一个CPU只能在一个时间点做一件事情,但是多核计算机可以完成并行。并发编程与计算机硬件的特性有很大关系。

      计算机的发展史,从早期的使用穿孔卡片,到后来的磁带,待现在的磁盘以及读取速度更快的固态硬盘。这些存储设备的一代代更新就是解决CPU利用率,用更快的存储设备与CPU一起工作。存储设备设备的更新迭代,但是做数据处理CUP,如果被占用就不能处理其他数据了。最初单道运行在计算机读取数据和打印数据时,计算机CPU仍处在闲置状态。在一个事件与一个时间之间读入和输出时CPU仍处在闲置状态。

      

      多道技术的应用优化了单道技术的不足。当处理事件A时,让磁盘读取时间B的程序,等待事件A在CPU中运行结束,运行事件B的程序。切换保存状态技术在其中得以运用,使计算机在时间上的复用和空间上的复用的方面都得到了提升。切换保存状态的特点是:当一个程序遇到I/O操作时,操作系统剥夺该程序的运行权限。当一个程序长时间占用CPU,操作系统也会剥夺该程序的运行权限,并且保存运行的状态。操作系统剥夺完程序运行权限后有进程调度。进程调度有四种方式,1,先来先运行方式。2,短作业优先调度方式。3,时间片转换方式。4,多级反馈队列。

      并发就是基于操作系统进程调度的属性,在运行多个程序时主观上看起来就是在同时运行,实际上是计算机的进程调度做到这种效果。

      计算机的进程。进程就是正在运行的程序。进程有三种状态,就绪态,运行态和阻塞态。将要运行进程可以成称之为就绪态,运行进程称之为运行态,当有事件请求,遇到I/O操作时就是处在阻塞态。

      同步与异步:表示的是任务的提交方式。在进程的同步是当程序运行时,任务被提交后等待任务结果出来。而进程的异步是当程序运行时,可以去做其他事情。

      阻塞与非阻塞态:阻塞就是进程运行的阻塞态,而非阻塞态就是。

    计算机可以同时启动多个进程,在python中也可以,启动多个进程的方式有两种,都是利用类的来创建。第一种是python中使用内置的类,第二种,自定义类。

    from multiprocessing import Process
    
    def task():
        print('子进程')
    if __name__ == '__main__':
        p = Process(target=task,)
        p.start()   # 告诉操作系统创建子进程的内存空间,
        print('主进程')
    结果:
    主进程
    子进程

      子进程的创建利用multiprocessing模块中的Process类。在创建子进程的过程:首先是在内存中开辟一块新的子进程的内存空间,将产生的代码copy进去。进程的特点是:每个进程都是一个独立的内存空间,且子进程的创建是随机,子进程的创建时与操作系统有关。使用‘if __name__ == '__main__'’,在内存空间类开辟一块子进程空间时,copy的代码会运行一遍,防止无限制创建进程。

    # 子进程创建第二种方式
    from multiprocessing import Process
    
    class MyProcess(Process):
        def __init__(self):
            super().__init__()
    
        def run(self):
            print('子进程')
    
    if __name__ == '__main__':
        p = MyProcess()
        p.start()
        print('主进程')

      在进程创建时,如果需要子进程运行完毕后再运行主进程需要join()方法。

    # jion()方法
    from multiprocessing import Process
    
    class MyProcess(Process):
        def __init__(self):
            super().__init__()
    
        def run(self):
            print('子进程')
    
    if __name__ == '__main__':
        p = MyProcess()
        p.start()
        p.join()    # jion方法 等待子进程结束后运行下一步程序
        print('主进程')

    僵尸进程与孤儿进程

      僵尸进程:就是之一些进程结束后占用的资源(PID等)没有被回收。自由使用join方法和父进程正常死亡后,才会回收子进程占用资源。

      孤儿进程:父进程非正常结束,子进程资源没有回收。Windows系统与Linux系统都有‘儿童福利院’,可以回收这些进行资源。

    守护进程:

      当一个进程结束,守护它的进程也结束。

    # 守护进程
    from multiprocessing import Process
    
    class MyProcess(Process):
        def __init__(self):
            super().__init__()
    
        def run(self):
            print('子进程')
    
    if __name__ == '__main__':
        p = MyProcess()
        p.daemon = True   # 设置子进程为守护进程,主进程结束,子进程也立即结束
        p.start()
        print('主进程')

    互斥锁

      模拟设置一个抢票情景。当有五个人抢票时,同一时间五个人都可以查到票,但是买票是只允许一个人买票,下一个人在买。否则存票的数据库信息错乱。

    from multiprocessing import Process, Lock
    import time, json, random
    
    def show_ticket(i):   # 查票
        with open('a', 'r', encoding='utf-8') as f:
            json_d = f.read()
            ticket = json.loads(json_d)
    
            f.flush()
        print(f'用户{i}正在查票,剩余票数:{ticket.get("ticket")}')
    
    def buy_ticket(i):  # 买票
        with open('a', 'r', encoding='utf-8') as f:
            json_d = f.read()
            ticket = json.loads(json_d)
        time.sleep(random.randint(1,5))   # 模拟网络延迟
        if ticket.get('ticket') > 0:
            ticket['ticket'] -= 1
            with open('a', 'w', encoding='utf-8') as f:
                json.dump(ticket, f)
                f.flush()
            print(f'用户{i}抢票成功')
    
        else:
            print(f'用户{i}抢票失败')
    
    def task(lock,i):
        show_ticket(i)
        lock.acquire()  # 抢锁
        buy_ticket(i)
        lock.release()  # 放锁
    
    if __name__ == '__main__':
    
        key = Lock()
        for i in range(1,6):
            p = Process(target=task, args=(key,i))  # 开启五个进程,经行抢票
            p.start()
        print('主进程结束')
    #结果
    主进程结束
    用户2正在查票,剩余票数:3
    用户1正在查票,剩余票数:3
    用户3正在查票,剩余票数:3
    用户4正在查票,剩余票数:3
    用户5正在查票,剩余票数:3
    用户2抢票成功
    用户1抢票成功
    用户3抢票成功
    用户4抢票失败
    用户5抢票失败
    互斥锁 模拟抢票

     进程之间的通信

       进程间的通信又称为IPC机制。利用队列进行数据交互。其中引入队列模块Queue。

    '''
    进程之间可与互相通信
        子进程间, 主进程与子进程间都可以通信
    '''
    from multiprocessing import Process, Queue
    def producer(q):   # 进程1
        q.put('hello')   # 在队列中添加元素
        q.put('hello, mm')
    
    def consumer(q):
        print(q.get_nowait())  # 获取队列元素,并打印
        
    if __name__ == '__main__':
        q = Queue()
        p1 = Process(target=producer,args=(q,) )
        c1 = Process(target=consumer, args=(q,))
        p1.start()
        c1.start()
        print(q.get())  # 主进程获取队列元素,并打印
    # 结果
    hello
    hello, mm

      

  • 相关阅读:
    ubuntu 从零安装tf-serving环境和opencv
    tensorflow pip install 安装指定版本的包并指定安装源(速度会快很多)
    Generative Adversarial Networks,gan论文的畅想
    ubuntu16 安装openssh-server 一直安装不上Unable to correct problems, you have held broken packages
    点乘(内积)和叉乘(外积、向量积)
    Ubuntu中清理Network下Connect to Server的入口
    tensorflow 之tensorboard 对比不同超参数训练结果
    tensorflow 高级api使用分布式之配置
    python opencv3 给图片加中文
    关于scp在zsh报错:zsh:no matches found :
  • 原文地址:https://www.cnblogs.com/huaiXin/p/11329260.html
Copyright © 2011-2022 走看看