python: with dan lock

Beberapa waktu yang lalu aku mencoba threading di python. Untuk sinkronisasi antar thread, aku mencoba menggunakan Lock yang ada di module threading. Kira2 seperti ini:

import threading, time

class VarWithLock():
    def __init__(self, a):
        self.a = 0
        self.lock = threading.Lock()

class MyThread(threading.Thread):
    def __init__(self, v):
        threading.Thread.__init__(self)
        self.v = v
    
    def run(self):
        for i in range(100):
	    self.v.lock.acquire()
            temp = self.v.a + 1
            time.sleep(0.01)
	    self.v.a = temp
	    self.v.lock.release()

v = VarWithLock(0)
for i in range(5):
    MyThread(v).start()

Kode tersebut menghasilkan hasil yang benar (di akhir semua thread selesai berjalan, nilai v.a adalah 500). (Jika tidak ada lock, hasilnya tidak benar karena thread akan berebut mengganti nilai v.a).

Melihat lagi dokumentasi python, aku mencoba untuk memakai with untuk mempermudah penulisan:

# di bagian awal (paling atas) ditambahi
from __future__ import with_statement

# di MyThread.run jadi seperti ini:
    with self.v.lock:
            temp = self.v.a + 1
            time.sleep(0.01)
            self.v.a = temp

Lebih simpel kan? Juga tidak usah khawatir mengenai lock yang ter-acquire() tapi lupa di-release(). Tapi hati-hati, bisa salah seperti ini:

    with self.v.lock:
            temp = self.v.a + 1
            if temp == 100:
                self.v = VarWithLock(-100)
            self.v.a = temp

Kode di atas tidak berjalan dengan benar karena Lock yang di-release() di akhir blok with bisa bukan Lock yang di-acquire() di awal!, sehingga, akan banyak thread yang tetap berhenti karena menunggu lock. Seharusnya kode di atas dibuat jadi seperti ini:

    with self.v.lock as lock:
            temp = self.v.a + 1
            if temp == 100:
                self.v = VarWithLock(-100)
            self.v.a = temp

Dengan begitu, lock tetap dengan aman di-release() walaupun isi self.v berubah.

One thought on “python: with dan lock

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s