Python çoklu görev programlama - iş parçacıkları arasında değişken paylaşımı

İlgili Etiketler:1. Python ile Web'inizi Güçlendirin
2. Shodan ve Python API

Sorun: İş parçacıkları arasında genel değişken verisi paylaşım hatası



import threading

g_num = 0


def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )

def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _


işlem sonucu:




Teorik olarak 1 milyon döngü gerçekleştirilir ve döngü her çalıştırıldığında genel değişkene 1 eklenir; nihai sonuç 2.000.000 olmalıdır. Gerçek sonuç yukarıda gösterilmektedir.

neden:



İki iş parçacığı aynı anda genel değişkenler üzerinde işlem yapar. İş parçacığı 1 genel değişkeni okuduğunda, iş parçacığı 2 de genel değişkeni okur. Bir değişken üzerinde işlem yapılırken, işlemden sonraki değişken değil, orijinal değişken okunur. İş parçacığı 1 değişken üzerindeki işlemden sonra işleme almadığı için, iş parçacığı 2 de önceki değişken değerini okumuştur.
Çözüm

Her seferinde yalnızca bir iş parçacığının veri üzerinde işlem yapmasını sağlamak için süreç eşzamanlama kullanın.

1. join() yöntemini kullanın

import threading

g_num = 0


def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )

def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
first.join ( ) _
second.start ( ) _
Sonuçlar:



Prensip: Program çalışırken first.join() iş parçacığı beklemeye alınır ve ikinci iş parçacığı ilk iş parçacığı tamamlandıktan sonra çalışmaya başlar; böylece aynı anda yalnızca bir iş parçacığının değişken üzerinde işlem yapması sağlanır.
İş parçacığı eşzamanlama: Bir görev yürütüldükten sonra başka bir görev yürütülebilir ve aynı anda yalnızca bir görev yürütülür.

2. Karşılıklı dışlama kilidi

import threading

g_num = 0

# Karşılıklı dışlama kilidi oluşturmak temelde şu fonksiyon aracılığıyla yapılır
LOCK = threading.Lock ( ) _
def task1 ():
# kilitle
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
# kilidi serbest bırak
LOCK.release ( ) _


def task2 ():
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
LOCK.release ( ) _


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _

Sonuçlar:





Prensip: Paylaşılan veri kilitlemede, aynı anda yalnızca bir iş parçacığı işlem yapar ve birden fazla iş parçacığı bunu birlikte almaya çalışır; threading içindeki kilit fonksiyonu ilk olarak bunu almak için kullanılır. İlk iş parçacığını çalıştırırken, önce mevcut iş parçacığını lock.acquire() ile kilitleyin; bu süre boyunca diğer iş parçacıkları çalışamaz. Döngü sona erdiğinde, mevcut iş parçacığını serbest bırakmak için lock.release() kullanın; bundan sonra diğer iş parçacıkları işlem yapabilir. Aynı anda yalnızca aynı iş parçacığının çalıştığından emin olun.
Ancak karşılıklı dışlama kilitleri kodun verimliliğini belirli bir ölçüde etkiler, çoklu görevi tek görevli yürütmeye dönüştürür ve ayrıca kilitlenme sorunlarına neden olabilir (kilitlerin zamanında serbest bırakılmamasından kaynaklanır).

Telif hakkı beyanı: Bu makalenin içeriği Alibaba Cloud'un gerçek adlı kayıtlı kullanıcıları tarafından sağlanmıştır. Telif hakkı orijinal yazara aittir. Alibaba Cloud geliştirici topluluğu telif hakkına sahip değildir ve ilgili yasal sorumluluğu üstlenmez. Belirli kurallar için lütfen «Alibaba Cloud Geliştirici Topluluğu Kullanıcı Hizmet Sözleşmesi» ve «Alibaba Cloud Geliştirici Topluluğu Fikri Mülkiyet Koruma Yönergeleri» belgelerine bakın. Bu toplulukta intihal şüphesi olan herhangi bir içerik bulursanız, bildirmek için ihlal şikayet formunu doldurun. Doğrulandıktan sonra, bu topluluk iddia edilen ihlal içeriğini derhal silecektir.

İlgili Makaleler

Daha Fazla Özel Teklifi Keşfedin

  1. Kısa Mesaj Hizmeti (SMS) & E-posta Hizmeti

    50.000 e-posta paketi 1,99 USD'den başlayan fiyatlarla, 120 kısa mesaj ise sadece 1,00 USD.

phone Bize Ulaşın
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.