• 进程


    一、进程理论
    1、程序和进程的区别
    程序:一堆代码
    进程:正在运行的程序
    进程是一个实体,每一个进程都有它自己独立的内存空间
    2、同步和异步
    同步:提交任务之后原地等待任务的返回结果,期间不做任何事
    异步:提交任务之后,不等待任务的返回结果,执行运行下一行代码
    3、阻塞与非阻塞:针对程序运行的状态
    阻塞:遇到io操作 >>>阻塞态
    非阻塞:就绪或者运行态 >>>就绪态 运行态
    二、开启进程的两种方式
    1、第一种
    from multiprocessing import Process
    import time
    
    
    def task(name):
        print('%s is running'%name)
        time.sleep(3)
        print('%s is over'%name)
    
    
    # 注意,在Windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍
    # 一定要写在if __name__ == '__main__':代码块里面
    # 强调:函数名一旦加括号,执行优先级最高,立刻执行
    if __name__ == '__main__':
        p1 = Process(target=task,args=('egon',))
        p1.start()     # 告诉操作系统创建一个进程
        print('')
    2、第二种
    from multiprocessing import Process
    import time
    
    
    class MyProcess(Process):
        def __init__(self,name):
            super().__init__()
            self.name = name
    
        # 必须写run方法
        def run(self):
            print('%s is running'%self.name)
            time.sleep(1)
            print('%s is over'%self.name)
    
    
    if __name__ == '__main__':
        obj = MyProcess('egon')
        obj.start()
        print('')
    三、join方法
    让主进程等待子进程运行完毕,即主进程在原地阻塞,而不影响子进程的运行
    from multiprocessing import Process
    import time
    
    
    def task(name,n):
        print('%s is running'%name)
        time.sleep(n)
        print('%s is over'%name)
    
    
    if __name__ == '__main__':
        start_time = time.time()
        p_list = []
        for i in range(3):
            p = Process(target=task,args=('子进程%s'%i,i))
            p.start()
            p_list.append(p)
        for i in p_list:
            i.join()
        print('',time.time()-start_time)
    四、进程之间数据隔离
    # 记住进程与进程之间数据是隔离的
    from multiprocessing import Process
    
    x = 100
    
    
    def task():
        global x
        x = 1
    
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        p.join()
        print('',x)
    五、进程对象其他相关方法
    from multiprocessing import Process,current_process
    import time
    import os
    
    
    def task():
        print('%s is running'%os.getpid())  # current_process().pid 获取自己的pid号
        time.sleep(3)
        print('%s is over'%os.getppid())    # 获取父进程pid号
    
    
    if __name__ == '__main__':
        p1 = Process(target=task)
        p1.start()
        p1.terminate()               # 杀死子进程
        time.sleep(0.1)
        print(p1.is_alive())         # 判断子进程是否存活
        print('')
    六、僵尸进程与孤儿进程
    两种情况下会回收子进程的pid等信息
    1、父进程正常结束
    2、join方法
    孤儿进程:父进程意外死亡
    Linux下:
    init孤儿福利院:用来回收孤儿进程所占用的资源
    代码实现:ps aux |grep 'Z'

    七、守护进程
    一旦主进程结束,子进程必定结束:
    from multiprocessing import Process
    import time
    
    
    def task(name):
        print('%s 正或者'%name)
        time.sleep(3)
        print('%s 正常死亡'%name)
    
    
    if __name__ == '__main__':
        p = Process(target=task,args=('子进程',))
        p.daemon = True    # 必须在p.start开启之前命令之前声明
        p.start()
        time.sleep(1)
        print('主进程正在死亡')
    八、互斥锁
    1、特点:
    牺牲了效率但是保证了数据的安全
    锁一定要在主进程中创建,给子进程用
    解决多个进程操作同一份数据,造成数据不安全的情况
    加锁会将并发变成串行
    锁通常用在对数据操作的部分,并不是对进程全程加锁
    mutex.acquire() # 抢锁 一把锁不能同时被多个人使用
    buy(i)
    mutex.release() # 释放锁
    2、实例:
    from multiprocessing import Process,Lock
    import json
    import time
    import random
    
    
    def search(i):
        with open('info','r',encoding='utf-8')as f:
            data = json.load(f)
        print('用户%s查询余票:%s'%(i,data.get('ticket')))
    
    
    def buy(i):
        with open('info','r',encoding='utf-8')as f:
            data = json.load(f)
        if data.get('ticket') > 0:
            data['ticket'] -= 1
            with open('info','w',encoding='utf-8')as f:
                json.dump(data,f)
            print('用户%s抢票成功'%i)
        else:
            print('用户%s查询余票为0'%i)
    
    
    def run(i,mutex):
        search(i)
        time.sleep(random.randint(1, 3))   # 模拟网络延迟
        mutex.acquire()
        buy(i)
        mutex.release()
    
    
    if __name__ == '__main__':
        mutex = Lock()
        for i in range(10):
            p = Process(target=run,args=(i,mutex))
            p.start()
  • 相关阅读:
    命令行参数(argc, argv)
    [转]CodeSmith和PowerDesigner的使用安装和数据库创建
    INADDR_ANY的确切含义
    C++的CreateThread实例
    浅谈VC++中预编译的头文件放那里的问题分析
    [转]Windows网络编程学习-面向连接的编程方式
    char 转wchar_t 及wchar_t转char
    connect函数详解
    正斜杠(/)与反斜杠()区别
    C/C++关于string.h头文件和string类
  • 原文地址:https://www.cnblogs.com/yanminggang/p/10820203.html
Copyright © 2020-2023  润新知