zoukankan      html  css  js  c++  java
  • DAY 33 进程理论与进程方法

    一.进程理论

      1.什么是进程,与程序的区别

       程序是一堆代码,而进程是指正在运行的程序

       进程是一个实体,每一个进程都有它自己独立的内存空间

      2.同步和异步:针对任务的提交方式

       同步:提交任务后原地等待任务的返回结果,期间不做任何事

       异步:提交任务后,不等待任务的返回结果,直接运行下一行代码

      3.阻塞和非阻塞:针对程序运行的状态

       阻塞:遇到IO操作>>> 阻塞态

       非阻塞:就绪或者运行态>>> 就绪态,运行态

    二.开启进程的两种方式

      1.直接通过Process类创建进程

      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__':

        p = Process(target = task,args = ('egon',)) # 实例化出一个对象

        p.start() # 告诉操作系统创建一个进程

        print('主') 

      2.通过自定义类继承Process类来创建进程

      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(3)

          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)

      # join的作用仅仅只是让主进程等待子进程的结束,不会影响其他子进程的运行

    四.进程之间内存隔离

      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) # 100

    五.进程对象的其他相关方法

      from multiprocessing import Process, current_process

      import time

      import os

      

      def task():

        print('%s is running' % os,getpid()) # % current_process().pid

        time.sleep(3)

        print('%s is over' % os.getppid()) # 获取父进程PID

      if __name__ == '__main__':

        p = Process(target=task)

        p.start()

        # p.terminate() # 杀死子进程

        # print(p.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=('egon',))

        p.daemon = True # 必须在p.start()开启进程命令之前声明

        p.start()

        print('主进程死亡') # 守护进程无论什么状态都直接死亡

    八.互斥锁(千万不能随意去使用)

      牺牲了效率但是保证了数据的安全

    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'%data.get('ticket'))
    
    
    def buy(i):
        # 买票之前还得先查有没有票!
        with open('info','r',encoding='utf-8') as f:
            data = json.load(f)
        time.sleep(random.randint(1,3))  # 模拟网络延迟
        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)
        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()

      锁一定要在主进程中创建,给子进程去用

      解决多个进程操作同一份数据,造成数据不安全的情况

      加锁会将并发变成串行

      锁通常用在对数据操作的部分,并不是对进程全程加锁

      

  • 相关阅读:
    maven打包
    Description Resource Path Location Type Project configuration is not up-to-d
    GoldenGate
    maven打包 把要的依赖也打进去 配置
    mysql如何优化where子句
    根据状态计算操作状态
    kafka direct模式
    Kafka Connect
    Kafka Streams
    如何看源码
  • 原文地址:https://www.cnblogs.com/majingjie/p/10819919.html
Copyright © 2011-2022 走看看