Skip to content

Instantly share code, notes, and snippets.

@manwar
Last active March 1, 2025 17:06
Show Gist options
  • Save manwar/e2915771fb709cc4379abd1d8aba7ea3 to your computer and use it in GitHub Desktop.
Save manwar/e2915771fb709cc4379abd1d8aba7ea3 to your computer and use it in GitHub Desktop.
Read/Write Lock in Perl and Python.

-- Back to Index --


Below is read/write lock in action in Python

[Source Code]

#!/usr/bin/env python3

import threading
from readerwriterlock import rwlock

reader = rwlock.RWLockFair().gen_rlock()
writer = rwlock.RWLockFair().gen_wlock()

rcount = 0
wcount = 0

def read_worker(id):
    global rcount
    global wcount

    with reader:
        rcount += 1
        if rcount == 1:
            writer.acquire()

    print(f"Reader {id} reads data: {wcount}")

    with reader:
        rcount -= 1
        if rcount == 0:
            writer.release()

def write_worker(id):
    global wcount

    with writer:
        wcount += 1
        print(f"Writer {id} writes data: {wcount}")

if __name__ == '__main__':
    for i in range(1, 3):
        threading.Thread(target=write_worker, args=(i,)).start()
    for i in range(1, 4):
        threading.Thread(target=read_worker, args=(i,)).start()

Running the code as below:

    $ python rw-lock.py
    Writer 1 writes data: 1
    Writer 1 writes data: 2
    Reader 1 reads data: 2
    Reader 2 reads data: 2
    Reader 3 reads data: 2
    $

The same now in Perl:

[Source Code]

#!/usr/bin/env perl

use v5.38;
use threads;
use threads::shared;
use Thread::Semaphore;

my $reader = Thread::Semaphore->new(1);
my $writer = Thread::Semaphore->new(1);

my $rcount :shared = 0;
my $wcount :shared = 0;

sub read_worker($id) {
    $reader->down();
    {
        lock($rcount);
        $rcount++;
        $writer->down() if ($rcount == 1);
    }
    $reader->up();
    say "Reader $id reads data: $wcount";
    $reader->down();
    {
        lock($rcount);
        $rcount--;
        $writer->up() if ($rcount == 0);
    }
    $reader->up();
}

sub write_worker($id) {
    $writer->down();
    $wcount++;
    say "Writer $id writes data: $wcount";
    $writer->up();
}

my @threads = map { threads->create(\&write_worker, $_) } 1..2;
push @threads, threads->create(\&read_worker, $_) for 1..3;
$_->join() for @threads;

Run the code now:

    $ perl rw-lock.pl
    Writer 1 writes data: 1
    Writer 1 writes data: 2
    Reader 1 reads data: 2
    Reader 2 reads data: 2
    Reader 3 reads data: 2
    $

-- Back to Index --


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment