Python’da Çoklu İşlem Oluşturma (Multi Process)

Bir önceki yazımda Thread ve Process kavramlarını açıklamıştım. Çoklu Thread ve Process ihtiyacından bahsedip Thread üzerine kısa bir örnek yapmıştım, şimdi de Process sayısını nasıl arttırabiliriz bunun üzerine bir şeyler söyleyeyim.

Yeni Process’ler oluşturmak için yine Thread benzeri bir Python modülümüz var. multiprocessing isimli bu modül içinde Process sınıfı ile işlemlerimizi yapacağız.

Pool Sınıfı: Havuz anlamındaki bu sınıf bize bir Process havuzu oluşturmamızı ve verdiğimiz işlemleri bu havuz içindeki process‘ler ile yapmamızı sağlar. Yönetimi onu oluşturan process’e aittir. Pool sınıfına ait metotların gösterildiği dokümantasyondaki küçük örneğe bakalım;

from multiprocessing import Pool
import time

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(processes=4) as pool:         # 4 işçi process'li Pool
        result = pool.apply_async(f, (10,)) # 1
        print(result.get(timeout=1))        # 2

        print(pool.map(f, range(10)))       # 3

        it = pool.imap(f, range(10))        # 4
        print(next(it))                     # "0" basar
        print(next(it))                     # "1" basar
        print(it.next(timeout=1))           # "4" basar

        result = pool.apply_async(time.sleep, (10,))
        print(result.get(timeout=1))

İşaretlediğim yerleri açıklamaya çalışayım.

1: bir process’te asenkron olarak fonksiyonumuzu çalıştırıyoruz
2: bir önceki işlemin sonucu getiriyoruz. Burada çok yavaş bir işlemciniz var ise sonuç henüz hazır olmayacağı için dönüş olmayabilir.
3: senkron bir biçimde 1den 10a kadar olan sayıların karesi konsola basılacaktır
4: “3”teki işlemin Generator bir fonksiyon dönen daha tembel hali ama büyük işlemlerde performanslı hali.

Metotlardaki timeout parametresi verilen sürede işlemin yapılmasını söyler yoksa “multiprocessing.TimeoutError” hatası verecektir.

Process sınıfını tek başına kullanımı ise Thread sınıfına benzer şekildedir. Yine dokümantasyon içindeki örneği açıklayayım.

from multiprocessing import Process
import os

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

def f(name):
    info('function f')
    print('hello', name)

if __name__ == '__main__':
    info('main line')
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

# çıktı şuna benzer olmalı
# main line
# module name: __main__
# parent process: 8744
# process id: 5276
# function f
# module name: __mp_main__
# parent process: 5276
# process id: 5756
# hello bob

Yine bir target parametresine fonksiyon adımızı vererek process’imizi başlattık. Oluşturduğumuz info fonksiyonu ve os modülü ile info fonksiyonunun çağrıldığı process hakkında bilgileri konsola bastık. Burada ilk process’in id’si ikinci process’in “parent id”si olmasına dikkat edelim.

Process’ler Arası İletişim

İki yol ile mümkün. Pipe ve Queue sınıfları. Queue için şu örneğe bakalım;

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # "[42, None, 'hello']"
    p.join()

Kod açık yeterince. Bir Queue nesnesi oluşturulup child process içinde atanan değere parent process içinde erişilebiliyor.

Pipe ise bize iki nesne döndürüyor ve bunları child ve parent process’lerde kullanmamızı istiyor.

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())   # "[42, None, 'hello']"
    p.join()

Daha çok çeviri gibi bir yazı oldu, standartlar belli az çok zaten yorum katılacak tek yer kod örnekleri olabilirdi herhalde. Kaynağı da buraya yazarak bitiriyorum https://docs.python.org/3.6/library/multiprocessing.html


Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

“Python’da Çoklu İşlem Oluşturma (Multi Process)” için bir cevap

  1. Melih

    Teşekkürler güzel bir özet olmuş.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir