Cobra/Keywords/lock

Материал из Викиучебника — открытых книг для открытого мира
Перейти к навигации Перейти к поиску

Lock[править]

lock указывает важный блок кода для выполнения.
Блок кода представляет собой критическую секцию, блокирующий поток, когда в блоке находится другой поток.
Эта конструкция гарантирует, что поток не может войти в критическую секцию кода пока другой поток находится в критической секции закрытой блокировкой.
При попытке входа другого потока в заблокированный код потребуется дождаться снятия блокировки объекта.

Синтаксис[править]

lock <expression> 
    <block>

Пример[править]

# Critical section is to generate output through a single shared writer fm multiple threads
class Tester
    var _statusWriter as Writer?
...
    cue init
    ...
        _statusWriter = MyWriter()
        # gen and setup multiple threads with .runInThread as the thread code to run
    ...
    
    def runInThread
        while true
            ...
            lock _statusWriter
                _statusWriter.writeLine(statusLine)

# This is the example from the C# lock doc page converted to cobra
use System.Threading

class Account
    var _thisLock  = Object()  # is private
    var balance as int
    var r = Random()

    cue init(initial as int) is public
        base.init
        .balance = initial

    def withdraw(amount as int) as int
        # This condition will never be true unless the lock statement
        # is commented out:
        if .balance < 0
            throw Exception("Negative Balance")

        # Comment out the next line to see the effect of leaving out 
        # the lock keyword:
        lock _thisLock
            if .balance >= amount
                print "Balance before Withdrawal :  ", .balance
                print "Amount to Withdraw        : -" , amount
                .balance = .balance - amount
                print "Balance after Withdrawal  :  ", .balance
                return amount
            else
                return 0 # transaction rejected

    def doTransactions is public
        for i in 0 : 100
            .withdraw(.r.next(1, 100))

class Test
    def main is shared
        threads = Thread[](10)
        acc = Account(1000)
        for i in 0 : 10
            t = Thread(ThreadStart(ref acc.doTransactions))
            threads[i] = t
        for i in 0 : 10
            threads[i].start