>  기사  >  백엔드 개발  >  Python 다중 프로세스에 대한 자세한 소개(예제 포함)

Python 다중 프로세스에 대한 자세한 소개(예제 포함)

不言
不言원래의
2018-09-20 17:23:434144검색

이 글의 내용은 PHP에서 SAPI가 무엇인지에 관한 것입니다. 달성하는 방법? (사진 및 텍스트) 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

Process

Python은 인터프리터에서 실행되는 언어입니다. 정보를 찾아보면 Python에 여러 프로세스를 사용할 때 전역 잠금(GIL)이 있다는 것을 알 수 있습니다. Thread) 이 상태에서는 멀티코어의 장점을 활용할 수 없습니다. 멀티프로세스를 사용하면 멀티 코어를 활용하여 효율성을 실제로 향상시킬 수 있습니다.
멀티 스레드 프로세스가 CPU 집약적이라면 멀티 스레드는 효율성을 크게 향상시키지 못합니다. 오히려 스레드 전환이 잦아 효율성이 저하될 수도 있습니다. ; IO 집약적 유형인 경우 멀티 스레드 프로세스는 IO 차단이 다른 스레드를 실행하기를 기다리는 동안 유휴 시간을 사용하여 효율성을 높일 수 있습니다.

프로세스 생성

Linux 및 Mac 시스템을 위한 특수 방법

1 Linux에서 하위 프로세스 생성 원칙:
1 ).부모 프로세스와 자식 프로세스는 부모 프로세스가 종료되면 자식 프로세스도 종료됩니다.
2) 먼저 부모 프로세스가 있고 그 다음에는 포크 기능을 통해 구현되는 자식 프로세스가 있습니다.

2. 포크 함수 반환 값: 이 메서드를 한 번 호출하고 두 번 반환합니다.

  • 생성된 하위 프로세스는 0을 반환합니다. 프로세스는 하위 프로세스의 pid를 반환합니다.

  • 3. Window에서도 포크 기능을 사용할 수 있나요?
  • Windows没有fork函数, Mac有fork函数(Unix -> Linux, Unix-> Mac),
    封装了一个模块multiprocessing

    4. 🎜🎜#

os.fork()

os.getpid(): 현재 프로세스의 pid를 가져옵니다. #🎜 🎜#
  • os.getppid(): 상위 프로세스 ID, 현재 프로세스의 상위 프로세스 ID 번호를 가져옵니다.

  • #🎜🎜 #
import  os
import  time
print("当前进程(pid=%d)正在运行..." %(os.getpid()))
print("当前进程的父进程(pid=%d)正在运行..." %(os.getppid()))
print("正在创建子进程......")
pid = os.fork()
pid2 = os.fork()
print("第1个:", pid)
print("第2个: ", pid2)

if pid == 0:
    print("这是创建的子进程, 子进程的id为%s, 父进程的id为%s"
          %(os.getpid(), os.getppid()))
else:
    print("当前是父进程[%s]的返回值%s" %(os.getpid(), pid))
time.sleep(100)
#🎜🎜 #win system
  • win 시스템에서 인스턴스화된 multiprocessing.Process를 사용하여 프로세스를 생성할 때 'if __name__=="__main__"'을 추가해야 합니다. 그렇지 않으면 다음 오류가 나타납니다. :

  • RuntimeError:
  • An attempt has been made to start a new process before the
    current process has finished its bootstrapping phase.
    
    This probably means that you are not using fork to start your
    child processes and you have forgotten to use the proper idiom
    in the main module:
    
       if __name__ == '__main__':
           freeze_support()
           ...
    
    The "freeze_support()" line can be omitted if the program
    is not going to be frozen to produce an executable.
    import  multiprocessing
    def job():
        print("当前子进程的名称为%s" %(multiprocessing.current_process()))
    if __name__=="__main__":    #win操作系统需要加上,否则会出现异常报错RuntimeError
    
        # 创建一个进程对象(group=None, target=None, name=None, args=(), kwargs={})
        p1 = multiprocessing.Process(target=job)
        p2 = multiprocessing.Process(target=job)
        # 运行多进程, 执行任务
        p1.start()
        p2.start()
    
        # 等待所有的子进程执行结束, 再执行主进程的内容
        p1.join()
        p2.join()
        print("任务执行结束.......")

  • multiprocessing.Process 클래스를 재정의하여 여러 프로세스 만들기

    from multiprocessing import Process
    import multiprocessing
    class JobProcess(Process):
        # 重写Process的构造方法, 获取新的属性
        def __init__(self,queue):
            super(JobProcess, self).__init__()
            self.queue = queue
        # 重写run方法, 将执行的任务放在里面即可
        def run(self):
            print("当前进程信息%s" %(multiprocessing.current_process()))
    
    if __name__=="__main__":
        processes = []
        # 启动10个子进程, 来处理需要执行的任务;
        for i in range(10):
            #示例化类,创建进程
            p = JobProcess(queue=3)
            processes.append(p)
            #启动多进程,执行任务
            p.start()
        #等待所有的子进程结束,再执行主进程
        [pro.join() for pro in processes]
        print("任务执行结束")

    Python 다중 프로세스에 대한 자세한 소개(예제 포함)Daemon

    데몬 스레드:

    setDeamon:
        True: 主线程执行结束, 子线程不再继续执行;
        Flase:

    데몬 프로세스:

      setDeamon:
        True: 主进程执行结束, 子进程不再继续执行;
        Flase:
    rrree Python 다중 프로세스에 대한 자세한 소개(예제 포함)

    프로세스 종료

    일부 프로세스는 무한 루프 작업을 수행할 수 있습니다. 이번에도 수동으로 프로세스를 종료합니다.# 🎜🎜#terminate()

    import multiprocessing
    import time
    def deamon():
        #守护进程:当主程序运行结束,子进程也结束
        name = multiprocessing.current_process()
        print("%s开始执行" %(name))
        time.sleep(3)
        print("执行结束")
    
    if __name__=="__main__":
        p1 = multiprocessing.Process(target=deamon,name='hello')
        p1.daemon = True
        p1.start()
        time.sleep(2)
        print("整个程序执行结束")

    Python 다중 프로세스에 대한 자세한 소개(예제 포함)

    컴퓨팅 집약적이며 I/O 집약적

    #🎜 🎜#컴퓨팅 집약적인 작업은 파이 계산, 비디오의 고화질 디코딩 등과 같이 CPU 리소스를 소비하는 많은 양의 계산이 모두 컴퓨팅에 의존하는 것이 특징입니다. CPU의 힘. 이러한 컴퓨팅 집약적인 작업은 멀티 태스킹으로도 완료할 수 있지만 작업이 많을수록 작업 전환에 더 많은 시간이 소요되고 작업 실행 시 CPU의 효율성이 낮아집니다. CPU 사용, 컴퓨팅 집약적 동시 작업 수는 CPU 코어 수와 동일해야 합니다. 컴퓨팅 집약적인 작업은 주로 CPU 리소스를 소비하므로 코드 실행 효율성이 중요합니다. Python과 같은 스크립팅 언어는 매우 비효율적으로 실행되며 계산 집약적인 작업에는 전혀 적합하지 않습니다. 계산 집약적인 작업의 경우 C 언어로 작성하는 것이 좋습니다.

    두 번째 유형의 작업은 IO 집약적입니다. 네트워크 및 디스크 IO와 관련된 작업은 모두 IO 집약적 작업입니다. 이 유형의 작업의 특징은 CPU 소비가 매우 적고 대부분이 IO 집약적이라는 것입니다. 작업 시간 그들은 모두 IO 작업이 완료되기를 기다리고 있습니다(IO의 속도가 CPU 및 메모리의 속도보다 훨씬 낮기 때문입니다). IO 집약적인 작업의 경우 작업이 많을수록 CPU 효율성은 높아지지만 한계가 있습니다. 가장 일반적인 작업은 웹 애플리케이션과 같은 IO 집약적인 작업입니다.

    멀티 프로세스와 멀티 스레드 비교

    멀티 프로세스 모드의 가장 큰 장점은 안정성이 높다는 것입니다. 왜냐하면 하위 프로세스가 충돌하더라도 영향을 미치지 않기 때문입니다. 메인 프로세스와 다른 하위 프로세스. (물론 마스터 프로세스가 중단되면 모든 프로세스가 중단되지만 마스터 프로세스는 작업 할당만 담당하므로 중단될 확률은 낮다.) 유명한 아파치는 처음으로 다중 프로세스 모드를 채택했다. Python 다중 프로세스에 대한 자세한 소개(예제 포함)다중 프로세스 모드의 단점은 프로세스 생성 비용이 높다는 것입니다. Unix/Linux 시스템에서는 Windows에서 프로세스를 생성하는 것이 비용이 많이 듭니다. 또한 운영 체제가 동시에 실행할 수 있는 프로세스 수도 메모리와 측면 모두에서 제한됩니다. CPU의 제한으로 인해 수천 개의 프로세스가 동시에 실행되면 운영 체제에 스케줄링 문제가 발생할 수도 있습니다.

    多线程模式通常比多进程快一点, 但是也快不到哪去, 而且, 多线程模式致命的缺点就是任何一个线程挂掉都可能直接造成整个进程崩溃, 因为所有线程共享进程的内存。 在Windows上, 如果一个线程执行的代码出了问题, 你经常可以看到这样的提示:“该程序执行了非法操作, 即将关闭”, 其实往往是某个线程出了问题, 但是操作系统会强制结束整个进程。
    这里通过一个计算密集型任务,来测试多进程和多线程的执行效率。

    import multiprocessing
    import threading
    from mytimeit import timeit
    
    class JobProcess(multiprocessing.Process):
        def __init__(self,li):
            super(JobProcess, self).__init__()
            self.li = li
        def run(self):
            for i in self.li:
                sum(i)
    
    
    class JobThread(threading.Thread):
        def __init__(self,li):
            super(JobThread, self).__init__()
            self.li = li
        def run(self):
            for i in self.li:
                sum(i)
    @timeit
    def many_processs():
        li = [[24892,23892348,239293,233],[2382394,49230,2321234],[48294,28420,29489]]*10
        processes = []
        for i in li :
            p = JobProcess(li)
            processes.append(p)
            p.start()
        [pro.join() for pro in processes]
        print("多进程执行任务结束,✌")
    @timeit
    def many_thread():
        #创建进程和销毁进程是时间的,如果li长度不够,会造成多线程快过多进程
        li = [[24892,23892348,239293,233],[2382394,49230,2321234],[48294,28420,29489]]*1000
        threads = []
        for i in li :
            t = JobThread(li)
            threads.append(t)
            t.start()
        [thread.join() for thread in threads]
        print("多线程执行任务结束,✌")
    if __name__ =="__main__":
        many_processs()
        many_thread()

    Python 다중 프로세스에 대한 자세한 소개(예제 포함)

    进程间通信-生产者消费者模型与队列

    演示了生产者和消费者的场景。生产者生产货物,然后把货物放到一个队列之类的数据结构中,生产货物所要花费的时间无法预先确定。消费者消耗生产者生产的货物的时间也是不确定的。
    通过队列来实现进程间的通信

    import multiprocessing
    import threading
    from multiprocessing import Queue
    
    class Producer(multiprocessing.Process):
        def __init__(self,queue):
            super(Producer, self).__init__()
            self.queue = queue
        def run(self):
            for i in range(13):
                #往队列添加内容
                self.queue.put(i)
                print("生产者传递的消息为%s" %(i))
            return self.queue
    
    class Consumer(multiprocessing.Process):
        def __init__(self,queue):
            super(Consumer, self).__init__()
            self.queue = queue
        def run(self):
            #获取队列内容
            #get会自动判断队列是否为空,如果是空, 跳出循环, 不会再去从队列获取数据;
            while True:
                print("进程获取消息为:%s" %(self.queue.get()))
    if __name__=="__main__":
        queue  = Queue(maxsize=100)
        p = Producer(queue)
        p.start()
        c = Consumer(queue)
        c.start()
        p.join()
        c.join(2)
        c.terminate()   #终止进程
        print("进程间通信结束,( •̀ ω •́ )y")

    Python 다중 프로세스에 대한 자세한 소개(예제 포함)

    위 내용은 Python 다중 프로세스에 대한 자세한 소개(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.