ホームページ >バックエンド開発 >Python チュートリアル >Python マルチプロセスの詳細な紹介 (例付き)

Python マルチプロセスの詳細な紹介 (例付き)

不言
不言オリジナル
2018-09-20 17:23:434191ブラウズ

この記事の内容は、PHP の SAPI とは何ですか?どのように達成するか? (写真と文章)、一定の参考価値がありますので、困っている友人の参考にしていただければ幸いです。

プロセス

Python はインタプリタ内で実行される言語です。情報を探していると、Python にはグローバル ロック (GIL) があり、複数のプロセスを使用する場合は使用できないことがわかります (マルチコアの利点。マルチプロセスを使用すると、マルチコアを活用して効率を真に向上させることができます。
マルチスレッドプロセスが CPU を集中的に使用する場合、マルチスレッドを使用しても効率はあまり向上しません。逆に、スレッドの頻繁な切り替えにより効率が低下する可能性もあります。マルチプロセスの使用をお勧めします。 ; IO 集中型の場合、マルチスレッド プロセスは IO ブロックを待機している間のアイドル時間を利用して他のスレッドを実行し、効率を向上させることができます。

プロセスの作成

Linux および Mac システム用の特別な方法

1. Linux で子プロセスを作成する原則:
1). 親プロセスと子プロセス、親プロセスが終了すると、子プロセスも終了します;
2) 最初に親プロセスがあり、次に子プロセスがあり、フォーク関数を通じて実装されます;

2。 fork 関数の戻り値: このメソッドを 1 回呼び出して 2 回戻ります。

  • 生成された子プロセスは 0

  • 親プロセスを返します。 process は子プロセスの pid を返します;

3. Window は fork 関数も使用できますか?

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("任务执行结束.......")

Python マルチプロセスの詳細な紹介 (例付き)

#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 マルチプロセスの詳細な紹介 (例付き)

デーモン プロセス

デーモン スレッド:

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 集約型のプロセス

コンピューティング集約型のタスクは、pi の計算、ビデオの高解像度デコードなど、大量の計算と CPU リソースの消費が特徴です。すべては CPU のコンピューティング能力に依存します。この種のコンピューティング集約型タスクはマルチタスクを使用して実行することもできますが、タスクの数が増えると、タスクの切り替えに時間がかかり、タスクを実行する際の CPU の効率が低下します。 CPU の使用、コンピューティング集約型 同時タスクの数は CPU コアの数と同じである必要があります。コンピューティング集約型のタスクは主に CPU リソースを消費するため、コードの実行効率が非常に重要です。 Python などのスクリプト言語は実行効率が非常に低く、計算負荷の高いタスクにはまったく適していません。計算負荷の高いタスクの場合は、C 言語で記述することをお勧めします。

2 番目のタイプのタスクは IO 集中型です。ネットワークおよびディスク IO を伴うタスクはすべて IO 集中型のタスクです。このタイプのタスクの特徴は、CPU 消費量が非常に少なく、ほとんどの場合、CPU 消費量が非常に少ないことです。タスクの内容は、IO 操作が完了するまで待機することです (IO の速度は CPU やメモリの速度よりもはるかに遅いため)。 IO 集中型のタスクの場合、タスクが多いほど CPU 効率は高くなりますが、制限があります。最も一般的なタスクは、Web アプリケーションなどの IO 集中型のタスクです。

マルチプロセスとマルチスレッドの比較

マルチプロセスモードの最大の利点は、サブプロセスがクラッシュしてもメインプロセスに影響を与えず、安定性が高いことです。他のサブプロセス。 (もちろん、マスタープロセスがハングアップすると、すべてのプロセスがハングアップしますが、マスタープロセスはタスクの割り当てのみを担当しており、ハングアップする確率は低いです) 有名なApacheが最初にマルチプロセスモードを採用しました。

マルチプロセス モードの欠点は、プロセス作成のコストが高いことです。Unix/Linux システムでは fork を呼び出しても問題ありませんが、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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。