マルチプロセスでの共有メモリValue&Array

4800 ワード

Python 3.8の新機能-マルチプロセス共有メモリで資料を調べる前にバージョンにもこの機能があります
Python 3.8では、multiprocessingモジュールはSharedMemoryクラスを提供し、異なるPythonプロセス間で共有メモリ領域を作成することができます.
旧バージョンのPythonでは,プロセス間共有データはファイルへの書き込み,ネットワークソケットによる送信,Pythonのpickleモジュールによるシーケンス化のみであった.共有メモリは、プロセス間でデータを転送するより速い方法を提供し、Pythonのマルチプロセッサとマルチコアプログラミングをより効率的にします.
共有メモリフラグメントは、単純なバイト領域として割り当てることもできるし、リストに類似した変更不可能なオブジェクトとして割り当てることもでき、デジタルタイプ、文字列、バイトオブジェクト、NoneオブジェクトなどのPythonオブジェクトの一部を保存することができる.
1共有メモリ
基本的な特徴:
(1)共有メモリは最も効率的なプロセス間通信方式であり、プロセスはデータのコピーを必要とせずにメモリを直接読み書きすることができる.
(2)カーネルは,複数のプロセス間で情報を交換するために,アクセスが必要なプロセスによって独自のプライベートアドレス空間にマッピングできるメモリ領域を特別に残している.プロセスは、データのコピーを必要とせずにメモリを直接読み書きすることができ、効率を大幅に向上させます.(ファイルマッピング)
(3)複数のプロセスがメモリを共有するため,何らかの同期メカニズムに依存する必要がある.
メリットとデメリット:
利点:プロセス間でのデータの迅速な転送
欠点:データセキュリティにリスクがあり、メモリの内容が他のプロセスで上書きまたは改ざんされる
注意:同期反発と頻繁に使用
 
2基本文法
共有メモリはC言語の使用文法に適合する
 from multiprocessing import Value , Array 
Value:1つの値をメモリに保存します.
Array:複数のデータをメモリに格納しますが、データ型が一致する必要があります.
 
補足:データ型
Type code
C Type
Python Type
Minimum size in bytes
Notes 'b'
signed char
int
1
  'B'
unsigned char
int
1
  'u'
Py_UNICODE
Unicode character
2
(1) 'h'
signed short
int
2
  'H'
unsigned short
int
2
  'i'
signed int
int
2
  'I'
unsigned int
int
2
  'l'
signed long
int
4
  'L'
unsigned long
int
4
  'q'
signed long long
int
8
(2) 'Q'
unsigned long long
int
8
(2) 'f'
float
float
4
  'd'
double
float
8
 
具体的な参考:8.7.  array  — Efficient arrays of numeric values
 
2.1 Value
 Value(typecode_or_type, *args, lock=True)  
機能:共有メモリオブジェクトを取得し、初期値、method of multiprocessingを格納します.
Returns a synchronized shared object(共有オブジェクトの同期)を返します.
typecode_or_type:戻りタイプ(C言語に変換されたストレージタイプ)を定義します.ctypesタイプか、ctypesタイプを表すcodeです.
*args:スペースを開き、args値を付与します.タイプに制限はありません.
注意:ctypesはpythonの外部関数ライブラリです.C言語と互換性のあるデータ型を提供し、DLsまたは共有ライブラリの関数を呼び出し、pythonでこれらのライブラリをラップするために使用できます.
from multiprocessing import Process,Value
import time
import random

def save_money(money):
    for i in range(100):
        time.sleep(0.1)
        money.value += random.randint(1,200)

def take_money(money):
    for i in range(100):
        time.sleep(0.1)
        money.value -= random.randint(1,150)

# money       ,       2000,     “i”
#           ,     2000,
money = Value('i',2000)

d = Process(target=save_money,args=(money,))#   money    ,    
d.start()
w = Process(target=take_money,args=(money,))#   money    ,    
w.start()

d.join()
w.join()

print(money.value)

運転4491
2.2 Array
 Array(typecode_or_type, size_or_initializer, *, lock=True) 
基本的にはValue,Returns a synchronized shared arrayに似ています
typecode_or_type:C言語に変換するストレージタイプを定義します.
size_or_initializer:共有メモリ領域を初期化し、
数値であれば、開いている共有メモリの領域サイズを表します(Valueは、その領域に数値をバインドすることを示します).
配列であれば、共有メモリに配列注が格納されていることを示します.ここでは、わざわざ見てみましたが、一次元配列しかなく、[[1,2,3,],[1,2,3]]のような多次元の
from multiprocessing import Process,Array

def fun(m,n):
    for i in range(n):
        print(m[i])

#       8     'i';
#     8   ,     i,        
m = Array('i',3)

p = Process(target= fun,args=(m,4))
p.start()

p.join()

うんてん
0 0 0
Process Process-1:
....
IndexError: invalid index

説明:3つの0は、オープンした共有メモリ容量が3であり、3を超えるとエラーが発生します.
例2
from multiprocessing import Process,Array
import time

def fun(m,n):
    for i in range(n):
        m[i]=i

m = Array('i',5)

p = Process(target= fun,args=(m,5))
p.start()

time.sleep(1)
for i in m:
    print(i)

p.join()

実行結果
0 1 2 3 4

time.sleep(1)を削除すると、出力結果はいずれも0になります.なぜなら、値を付けずに印刷されたからです.
from multiprocessing import Process,Array
import time

def fun(m,n):
    for i in range(n):
        print(m[i])
        m[i]=i

#       5   ,          
m = Array('i',[1,2,3,4,5])

p = Process(target= fun,args=(m,5))
p.start()

time.sleep(1)
for i in m:
    print(i)

p.join()

うんてん
1 2 3 4 5
0 1 2 3 4

2番目のパラメータは、1つの数値が入力された場合、共有メモリにどれだけのスペースが開かれているかを示します.
リストが入力されている場合は、応答要素数の共有空間容量を開き、共有空間に直接格納します.