ProgramlamaPython geliştiricisi

Python'da iş parçacıkları veya süreçler arasında karmaşık nesnelerin (örneğin, sözlük listeleri) aktarılması sırasında ne olur? Değiştirilebilir koleksiyonlarla ilgili çoklu iş parçacığı ve çoklu süreç uygulamaları programlarken nelere dikkat etmek önemlidir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Python'da iş parçacıkları ile çalışırken, bellek içindeki nesneler tüm iş parçacıkları tarafından kopya edilmeden hemen erişilebilir. Ancak, süreçlerle çalışırken multiprocessing kullanıldığında, standart Python nesneleri (örneğin, listeler, sözlükler) süreçler arasında serileştirme (genellikle pickle aracılığıyla) ile aktarılır ve her süreç nesnenin kendi kopyasını alır. Bir süreçteki nesnenin değiştirilmesi başka bir süreçteki kopyayı etkilemez.

Ana Farklar:

  • İş Parçacığı (threading): Tüm iş parçacıkları genel bir adres alanında çalışır. Herhangi bir nesne (iç içe koleksiyonlar da dahil) paylaşılır.
  • Çoklu Süreç (multiprocessing): Her süreç kendi belleğine sahiptir; nesneler serileştirme aracılığıyla aktarılır. Süreçler arasında iletişim kurmak için özel yapılar kullanılmalıdır, örneğin multiprocessing.Manager().dict().

Örnek:

# Çoklu Süreç from multiprocessing import Process, Manager def worker(d): d['a'] = 42 if __name__ == '__main__': # Basit bir dict süreçler arasında çalışmaz managed_dict = Manager().dict() p = Process(target=worker, args=(managed_dict,)) p.start(); p.join() print(managed_dict['a']) # 42
  • Eğer normal bir dict kullanılsaydı, süreçteki değişiklikler ana süreçte görünmezdi.

Tuzak Sorusu.

Normal bir listeyi (list) bir süreçte düzenlemek diğer bir süreçte nasıl yansır?

Cevap:

Asla, eğer multiprocessing ile çalışıyorsanız. Normal Python nesneleri süreçler arasında paylaşılmaz. Paylaşım için özel yapılar — Manager nesneleri (örneğin, Manager().list(), Manager().dict.) kullanmak gerekir; bu nesneler süreçler arasındaki durumu senkronize eder.

Konunun inceliklerini bilmediği için yaşanan bazı hataların örnekleri.


Hikaye

Web tarayıcısı geliştirme ekibi görev kuyruklarını listeler olarak başlattı ve onları multiprocessing ile süreçler arasında paylaştı. Görevler "kayboldu" çünkü süreçler birbirlerinin güncellemelerini göremedi. Manager().list() kullanarak düzeltildi.


Hikaye

Analitik hizmette, logları iş parçacıkları içinde iç içe dict'lerde toplamaya çalıştılar. Yüksek hacimli senaryolarda bu durum yarış koşullarına ve verilerin bozulmasına yol açtı; çünkü kilitler eksikti.


Hikaye

ETL hizmetinde, işleme aşamasında toplanan verilerin nesnelerini birçok süreçte toplamaya çalışırken verilerin kopyalanması/kayıp olması tespit edildi: programcılar her sürecin bir yapı kopyası ile çalıştığını ve ortak bir yapı ile değil, bunun farkında değildi.