İletişim Süreçleri
Süreç içi iletişim, süreçler arasında veri alışverişi anlamına gelir. Paralel uygulamanın geliştirilmesi için süreçler arasında veri alışverişi yapmak gerekir. Aşağıdaki şema, birden çok alt süreç arasında senkronizasyon için çeşitli iletişim mekanizmalarını göstermektedir -
Çeşitli İletişim Mekanizmaları
Bu bölümde, çeşitli iletişim mekanizmaları hakkında bilgi edineceğiz. Mekanizmalar aşağıda açıklanmıştır -
Kuyruklar
Kuyruklar, çok işlemli programlarla kullanılabilir. Queue sınıfımultiprocessing modül benzer Queue.Queuesınıf. Dolayısıyla aynı API kullanılabilir.Multiprocessing.Queue bize süreçler arasında iş parçacığı ve işlem güvenli FIFO (ilk giren ilk çıkar) iletişim mekanizması sağlar.
Misal
Aşağıda, çoklu işlemin Queue sınıfı kavramını anlamak için python resmi belgelerinden çoklu işlemeyle ilgili basit bir örnek verilmiştir.
from multiprocessing import Process, Queue
import queue
import random
def f(q):
q.put([42, None, 'hello'])
def main():
q = Queue()
p = Process(target = f, args = (q,))
p.start()
print (q.get())
if __name__ == '__main__':
main()
Çıktı
[42, None, 'hello']
Borular
Çok işlemli programlarda süreçler arasında iletişim kurmak için kullanılan bir veri yapısıdır. Boru () işlevi, varsayılan olarak çift yönlü (iki yönlü) olan bir boru ile bağlanmış bir çift bağlantı nesnesi döndürür. Aşağıdaki şekilde çalışır -
Borunun iki ucunu temsil eden bir çift bağlantı nesnesi döndürür.
Her nesnenin iki yöntemi vardır - send() ve recv(), süreçler arasında iletişim kurmak için.
Misal
Aşağıdaki, python resmi belgelerinden alınan çoklu işlem kavramını anlamak için basit bir örnektir. Pipe() çoklu işlemenin işlevi.
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target = f, args = (child_conn,))
p.start()
print (parent_conn.recv())
p.join()
Çıktı
[42, None, 'hello']
Yönetici
Yönetici, tüm kullanıcıları arasında paylaşılan bilgileri koordine etmenin bir yolunu sağlayan bir çoklu işlem modülü sınıfıdır. Yönetici nesnesi, paylaşılan nesneleri yöneten ve diğer işlemlerin bunları değiştirmesine izin veren bir sunucu işlemini kontrol eder. Başka bir deyişle, yöneticiler, farklı süreçler arasında paylaşılabilen verileri oluşturmanın bir yolunu sağlar. Yönetici nesnesinin farklı özellikleri aşağıdadır -
Yöneticinin temel özelliği, paylaşılan nesneleri yöneten bir sunucu sürecini kontrol etmektir.
Bir diğer önemli özellik, herhangi bir işlem değiştirdiğinde tüm paylaşılan nesneleri güncellemektir.
Misal
Aşağıda, sunucu işleminde bir liste kaydı oluşturmak ve ardından bu listeye yeni bir kayıt eklemek için yönetici nesnesini kullanan bir örnek verilmiştir.
import multiprocessing
def print_records(records):
for record in records:
print("Name: {0}\nScore: {1}\n".format(record[0], record[1]))
def insert_record(record, records):
records.append(record)
print("A New record is added\n")
if __name__ == '__main__':
with multiprocessing.Manager() as manager:
records = manager.list([('Computers', 1), ('Histoty', 5), ('Hindi',9)])
new_record = ('English', 3)
p1 = multiprocessing.Process(target = insert_record, args = (new_record, records))
p2 = multiprocessing.Process(target = print_records, args = (records,))
p1.start()
p1.join()
p2.start()
p2.join()
Çıktı
A New record is added
Name: Computers
Score: 1
Name: Histoty
Score: 5
Name: Hindi
Score: 9
Name: English
Score: 3
Yöneticide Ad Alanları Kavramı
Yönetici Sınıfı, birden çok işlemde çeşitli öznitelikleri paylaşmanın hızlı bir yolu olan ad alanları kavramıyla birlikte gelir. Ad alanları çağrılabilen herhangi bir genel yöntem içermez, ancak yazılabilir niteliklere sahiptir.
Misal
Aşağıdaki Python komut dosyası örneği, ana süreç ve alt süreç boyunca veri paylaşmak için ad alanlarını kullanmamıza yardımcı olur -
import multiprocessing
def Mng_NaSp(using_ns):
using_ns.x +=5
using_ns.y *= 10
if __name__ == '__main__':
manager = multiprocessing.Manager()
using_ns = manager.Namespace()
using_ns.x = 1
using_ns.y = 1
print ('before', using_ns)
p = multiprocessing.Process(target = Mng_NaSp, args = (using_ns,))
p.start()
p.join()
print ('after', using_ns)
Çıktı
before Namespace(x = 1, y = 1)
after Namespace(x = 6, y = 10)
Ctypes-Array ve Değer
Çoklu işlem modülü, verileri paylaşılan bir bellek haritasında depolamak için Dizi ve Değer nesneleri sağlar. Array paylaşılan bellekten ayrılmış bir ctypes dizisidir ve Value paylaşılan bellekten ayrılmış bir ctypes nesnesidir.
Çoklu işlemden İşlem, Değer, Dizi ile birlikte olmak.
Misal
Aşağıdaki Python betiği, işlemler arasında bazı verileri paylaşmak için Ctypes Array ve Value kullanmak için python belgelerinden alınan bir örnektir.
def f(n, a):
n.value = 3.1415927
for i in range(len(a)):
a[i] = -a[i]
if __name__ == '__main__':
num = Value('d', 0.0)
arr = Array('i', range(10))
p = Process(target = f, args = (num, arr))
p.start()
p.join()
print (num.value)
print (arr[:])
Çıktı
3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
Sıralı Süreçleri İletme (CSP)
CSP, sistemlerin eşzamanlı modeller içeren diğer sistemlerle etkileşimini göstermek için kullanılır. CSP, mesaj geçişi yoluyla eşzamanlı veya program yazmak için bir çerçevedir ve bu nedenle eşzamanlılığı tanımlamak için etkilidir.
Python kitaplığı - PyCSP
CSP'de bulunan temel ilkelleri uygulamak için Python, PyCSP adlı bir kitaplığa sahiptir. Çok kolay anlaşılabilmesi için uygulamayı çok kısa ve okunaklı tutar. PyCSP'nin temel işlem ağı aşağıdadır -
Yukarıdaki PyCSP işlem ağında, iki süreç vardır - İşlem1 ve İşlem 2. Bu işlemler, mesajları iki kanaldan - kanal 1 ve kanal 2 - geçirerek iletişim kurar.
PyCSP'yi Kurmak
Aşağıdaki komutun yardımıyla Python kitaplığı PyCSP'yi kurabiliriz -
pip install PyCSP
Misal
Aşağıdaki Python betiği, iki işlemi paralel olarak çalıştırmak için basit bir örnektir. PyCSP python kitaplığı yardımıyla yapılır -
from pycsp.parallel import *
import time
@process
def P1():
time.sleep(1)
print('P1 exiting')
@process
def P2():
time.sleep(1)
print('P2 exiting')
def main():
Parallel(P1(), P2())
print('Terminating')
if __name__ == '__main__':
main()
Yukarıdaki kodda iki işlev, yani P1 ve P2 oluşturuldu ve sonra süslendi @process bunları süreçlere dönüştürmek için.
Çıktı
P2 exiting
P1 exiting
Terminating