zoukankan      html  css  js  c++  java
  • Day34

    今日内容:

      1、开启进程的两种方法;

      2、join方法;

      3、进程之间内存空间互相隔离;

      4、进程对象其他相关的属性或方法;

      5、僵尸进程与孤儿进程;

      6、守护进程;

      7、互斥锁

    一、开启进程的两种方式:

    开启子进程的方式一:

    from multiprocessing import Process
    import time
    
    def task(name):
        print('%s is running' %name)
        time.sleep(3)
        print('%s is done' %name)
    
    # 在windows系统上,开启子进程的操作必须放到if __name__ == '__main__'的子代码中
    if __name__ == '__main__':
        p=Process(target=task,args=('egon',)) #Process(target=task,kwargs={'name':'egon'})
        p.start() # 只是向操作系统发送了一个开启子进程的信号
        print('主进程')
    View Code

    开启子进程的方式二:

    from multiprocessing import Process
    import time
    
    
    class Myprocess(Process):
        def __init__(self, name):
            super().__init__()
            self.name = name
    
        def run(self):
            print('%s is running' % self.name)
            time.sleep(3)
            print('%s is done' % self.name)
    
    
    # 在windows系统上,开启子进程的操作必须放到if __name__ == '__main__'的子代码中
    if __name__ == '__main__':
        p = Myprocess('egon')
        p.start()  # 只是向操作系统发送了一个开启子进程的信号
        print('主进程')
    View Code

    二、join方法:

    主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。需要强调的是,p.join只能join住start开启的进程

    简单来说,就是join让主进程在原地等待,等待子进程运行完毕,不会影响子进程的执行

    from multiprocessing import Process
    import time
    
    
    def task(name,n):
        print('%s is running'%name)
        time.sleep(n)
        print('%s is done'%name)
    
    
    if __name__ == '__main__':
        p1=Process(target=task,args=('p1',1))
        p2 = Process(target=task, args=('p2', 2))
    
        p1.start()
        p2.start()
    
        p1.join()
        p2.join()
        print('主程序')
    案例

    三、进程之间内存空间互相隔离

    虽然进程之间是空间上的复用,但是在内存中其实每个进程之间都是在物理层面上隔开的,接下来就用代码来验证

    from multiprocessing import Process
    
    
    n=100
    def task():
        global n
        n=0
        print('子进程n=',n)#0
    
    
    if __name__ == '__main__':
        p1=Process(target=task)
        p1.start()
        p1.join()
        print('主进程n=',n)#100

    主进程与子进程之间互不干扰,子进程是对主进程的拷贝。

    四、进程对象其他的相关属性

    1. pid:进程的唯一ID号
        1. current_process().pid: 当前进程的ID号
        2. os.getpid: 当前进程的ID号
        3. os.getppid: 当前进程的父进程ID号
    2. name: 当前进程的name
    3. p.terminate(): 强制终止进程p
    4. p.is_alive(): 如果p仍然运行,返回True

    from multiprocessing import Process,current_process
    import time,os
    def task():
        print('%s is runing father is %s'%(os.getpid(),os.getppid()))
    
        print('%s is done'%os.getpid())
    
    if __name__ == '__main__':
        p = Process(target=task,name='子进程')
        print(p.name)
        p.start()
        p.terminate()#关闭进程,不会立即关闭,所以is_alive立刻查看的结果可能还是存活
        print(p.is_alive())#判断进程是否关闭,返回是True
        time.sleep(0.1)
        print(p.is_alive())#返回是False
        print('主进程',os.getpid(),os.getppid())
    
    进程对象的terminate,is_alive方法和name属性
    View Code

    五、僵尸进程与孤儿进程

      基本概念:

      在unix/linux中,正常情况下,子进程都是通过父进程创建的,子进程再创建新的进程,子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束.当一个进程完成它的工作之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态.

      孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程,孤儿进程将被init进程所收养,并由init进程对它们完成状态收集工作

      僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait()或waitpid()获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中.

    六、守护进程

    本质就是一个"子进程",该"子进程"的生命周期<=被守护进程的生命周期

    from multiprocessing import Process
    import time
    
    
    def task(name):
        print('%s is 活着'%name)
        time.sleep(3)
        print('%s is 死了'%name)
    
    
    if __name__ == '__main__':
        p=Process(target=task,args=('egon',))
        p.daemon=True
        p.start()
        time.sleep(1)
        print('主正在死')
    View Code

    七、互斥锁

    每个线程互相独立,相互之间没有任何关系,但是在同一个进程中的资源,线程是共享的,如果不进行资源的合理分配,对数据造成破坏,使得线程运行的结果不可预期。这种现象称为“线程不安全”。

    某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

    import json
    import time,random
    from multiprocessing import Process,Lock
    
    def search(name):
        with open('db.json','rt',encoding='utf-8') as f:
            dic=json.load(f)
        time.sleep(1)
        print('%s 查看到余票为 %s' %(name,dic['count']))
    
    def get(name):
        with open('db.json','rt',encoding='utf-8') as f:
            dic=json.load(f)
        if dic['count'] > 0:
            dic['count'] -= 1
            time.sleep(random.randint(1,3))
            with open('db.json','wt',encoding='utf-8') as f:
                json.dump(dic,f)
                print('%s 购票成功' %name)
        else:
            print('%s 查看到没有票了' %name)
    
    def task(name,mutex):
        search(name) #并发
        mutex.acquire()
        get(name) #串行
        mutex.release()
    
        # with mutex:
        #     get(name)
    
    if __name__ == '__main__':
        mutex = Lock()
        for i in range(10):
            p=Process(target=task,args=('路人%s' %i,mutex))
            p.start()
            # p.join() # join只能将进程的任务整体变成串行
    案例:抢票
  • 相关阅读:
    False注入,以及SQL注入技巧总结
    xdebug插件攻击
    RPO攻击
    教务处sso设计缺陷
    MD5的Hash长度扩展攻击
    AMAZON PRICE TRACKER, AMAZON PRICE HISTORY, AMAZON PRICE DROP ALERT | DROPGG.COM
    弄懂JDK、JRE和JVM之间的联系。
    MyBatis配置及学习
    Cannot forward after response has been committed 异常原因
    bbs论坛中的问题和心得。(更新)
  • 原文地址:https://www.cnblogs.com/Mister-JH/p/9594143.html
Copyright © 2011-2022 走看看