マルチスレッドとマルチプロセス、コラボレーションの理解

11232 ワード

マルチスレッドとマルチプロセスの理解
スレッドとは
スレッドは、オペレーティングシステムが演算スケジューリングを行うことができる最小単位です.プロセスに含まれ、プロセス内の実際の動作単位です.1つのスレッドとは、プロセス内の単一の順序の制御フローを指し、1つのプロセスで複数のスレッドを同時に実行することができ、各スレッドは並列に異なるタスクを実行します.1つのスレッドはexecution context(実行コンテキスト)、すなわちcpuの実行に必要な一連の命令である.
プロセスとは
プロセスとは、プログラムが所与のデータセット上で実行するプロセスであり、システムがリソース割り当てと実行呼び出しを行う独立した単位である.オペレーティングシステムで実行中のプログラムとして簡単に理解できます.つまり、アプリケーションごとに独自のプロセスがあります.
各プロセスが開始されると、最初にスレッド、すなわちプライマリスレッドが生成されます.プライマリ・スレッドは、他のサブスレッドを作成します.
両者の区別
1.同じプロセスのスレッドは同じメモリ領域を共有しますが、プロセス間は独立しています.2.同じプロセス内のすべてのスレッドのデータは共有(プロセス通信)であり、プロセス間のデータは独立している.3.プライマリ・スレッドの変更は他のスレッドの動作に影響を与える可能性がありますが、親プロセスの変更(削除以外)は他のサブプロセスに影響を与えません.4.スレッドはコンテキストの実行命令であり、プロセスは演算に関連するリソースのクラスタである.5.同じプロセスのスレッド間で直接通信できますが、プロセス間のコミュニケーションは中間エージェントによって実現される必要があります.6.新しいスレッドを作成するのは簡単ですが、新しいプロセスを作成するには親プロセスをコピーする必要があります.7.1つのスレッドは、同じプロセスの他のスレッドを操作できますが、プロセスはそのサブプロセスのみを操作できます.8.スレッドの起動速度が速く、プロセスの起動速度が遅い(ただし、両者の実行速度は比べものにならない).
GIL
マルチプロセスといえばPythonのGILはpython以外の環境では、シングルコアの場合、同時に1つのタスクしか実行できないと言わざるを得ません.マルチコアの場合、複数のスレッドが同時に実行されることをサポートします.しかしpythonでは、コアの数にかかわらず、1つのスレッドしか実行できません.その原因を究明すると、これはGILの存在によるものである.
GILのフルネームはGlobal Interpreter Lock(グローバル解釈ロック)であり、ソースはpython設計当初の考慮であり、データセキュリティのための決定である.あるスレッドを実行するには、まずGILを取得する必要があります.GILを「通行証」と見なすことができます.pythonプロセスでは、GILは1つしかありません.通行証のスレッドが取れなければ、CPUに入って実行することは許されません.GILはcpythonにしかありません.cpythonはc言語のオリジナルスレッドを呼び出しているので、cpuを直接操作することはできません.GILを利用して同じ時間に1つのスレッドしかデータを取得できないことを保証するしかありません.pypyやjpythonにはGILはありません.
プロセス
Pythonはマルチプロセス操作を行うにはmuiltprocessingライブラリを使用する必要があります.その中のProcessクラスはthreadingモジュールのThreadクラスに似ています.コードを直接見てマルチプロセスを熟知しています

from multiprocessing import Process

def run(num):
    print('hello  process')
    for i in range(5):
        print(num,i)
if __name__ =='__main__':
    for i in  range(5):
        proces = Process(target=run,args=(i,))#      
        proces.start()#  
        proces.join() #             ,    ,        

スレッド
Pythonは2つのモジュールを提供してマルチスレッドの操作を行い、それぞれthreadとthreadingであり、前者は比較的低級なモジュールであり、より下層の操作に用いられ、一般的な応用レベルの開発はよく使われない.

import threading
def run(num):
    print('hello threading')
    for i in range(5):
        print('%s -- %d' % (threading.current_thread().name, i))#     'threading.current_thread().name'                

if __name__ == '__main__':
    for i in  range(5):
        thread = threading.Thread(target=run, args=(i,))#      
        thread .start()#    

マルチプロセスまたはマルチスレッドの選択
CPU密集型:プログラムは計算に偏り、CPUを頻繁に使用して演算する必要がある.例えば科学計算のプログラム、機械学習のプログラムなど.I/O密集型:その名の通り、プログラムは頻繁に入出力操作を行う必要がある.爬虫類プログラムは典型的なI/O密集型プログラムである.
プログラムがCPU密集型の場合は、マルチプロセスを推奨します.マルチスレッドはI/O密集型プログラムに適用するのに適しています.
きょうてい
コパスの存在意義:マルチスレッドアプリケーションに対して、CPUはスライス方式でスレッド間の実行を切り替え、スレッドの切り替えに時間がかかる.コンシステントでは、1つのスレッドのみを使用して、1つのスレッドを分解して複数の「マイクロスレッド」となり、1つのスレッドにコードブロックの実行順序を規定します.コンシステントの適用シーン:プログラム中にCPUを必要としない操作が多数存在する場合(IO).サードパーティモジュールgeventとgreenletはよく使用されます.(本質的には、geventはgreenletの高度なパッケージなので、一般的にはそれを使えばいいです.これはかなり効率的なモジュールです.)
簡単な協程爬虫類

from urllib import  request
import  ssl
import gevent
from  gevent import  monkey

#         IO         
monkey.patch_all()
ssl._create_default_https_context = ssl._create_unverified_context

def spider(url):
    print('GET:%s' %url)
    resp = request.urlopen(url)
    print(resp)
    data = resp.read()
    f = open("test.html","wb")
    f.write(data)
    f.close()
    print("%d --------------- %s" %(len(data),url))

gevent.joinall([gevent.spawn(f,'http://www.qiushibaike.com/'),
                gevent.spawn(f,'http://news.qq.com/'),
                gevent.spawn(f,'http://www.toutiao.com/'),
                ])

きょうていの利点
1:スレッドを単一スレッドの下で切り替え、資源消費を減らす2:原子操作制御フローを必要とせず、プログラミングモデルを簡略化する3:高同時、高拡張、低コスト.