Readers-writer ๋ฝ

Readers-writer ๋ฝ(RW Lock)์€ ์ฝ๊ธฐ๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค์™€ ์“ฐ๊ธฐ๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์˜ ๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ธฐ๋ฒ•์ด๋‹ค. RW ๋ฝ์€ ๊ฒฝ์Ÿ ์ƒํƒœ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” ์“ฐ๊ธฐ ์—ฐ์‚ฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ์“ฐ๊ธฐ๋งŒ ๋ฐฐํƒ€์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ด€์ฐฐ์— ๊ธฐ๋ฐ˜ํ•œ๋‹ค.

RW ๋ฝ์€ ๋‹ค์Œ ์ œ์•ฝ์„ ๋งŒ์กฑํ•˜๋„๋ก ๋ฐฐํƒ€ ์ œ์–ด๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • ๋ฝ์„ ํš๋“ฑ ์ค‘์ธ reader๋Š” ๊ฐ™์€ ์‹œ๊ฐ์— 0๊ฐœ ์ด์ƒ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฝ์„ ํš๋“ ์ค‘์ธ writer๋Š” ๊ฐ™์€ ์‹œ๊ฐ์— 1๊ฐœ๋งŒ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • reader์™€ writer๋Š” ๊ฐ™์€ ์‹œ๊ฐ์— ๋ฝ ํš๋“ ์ƒํƒœ๊ฐ€ ๋  ์ˆ˜ ์—†๋‹ค.

์Šคํ•€๋ฝ ๊ธฐ๋ฐ˜ RW ๋ฝ ๊ตฌํ˜„

void rwloack_read_acquire(int *rcnt, volatile int *wcnt) {
    while (1) {
        while (*wcnt); // writer๊ฐ€ ์žˆ์œผ๋ฉด ๋Œ€๊ธฐํ•œ๋‹ค.
        __sync_fetch_and_add(rcnt, 1);
        if (*wcnt == 0) { // writer๊ฐ€ ์—†์œผ๋ฉด ๋ฝ์„ ํš๋“ํ•œ๋‹ค.
            break;
        }
        __sync_fetch_and_sub(rcnt, 1)
    }
}

void rwlock_read_release(int *rcnt) {
    __sync_fetch_and_sub(rcnt, 1);
}

void rwlock_write_acquire(bool *lock, volatile int *rcnt, int *wcnt) {
    __sync_fetch_and_add(wcnt, 1);
    while (*rcnt); // reader๊ฐ€ ์žˆ์œผ๋ฉด ๋Œ€๊ธฐํ•œ๋‹ค.
    spinlock_acquire(lock);
}

void rwlock_write_release(bool *lock, int *wcnt) {
    spinlock_release(lock);
    __sync_fetch_and_sub(wcnt, 1);
}
int rcnt = 0;
int wcnt = 0;
bool lock = false;

void reader() {
    while (1) {
        rwlock_read_acquire(&rcnt, &wcnt);
        // critical section (read only)
        rwlock_read_release(&rcnt);
    }
}

void writer() {
    while (1) {
        rwlock_write_acquire(&lock, &rcnt, &wcnt);
        // critical section (write only)
        rwlock_write_release(&lock, &wcnt);
    }
}

๋Ÿฌ์ŠคํŠธ์—์„œ RW ๋ฝ ์‚ฌ์šฉ

use std::sync::RwLock;

fn main() {
    let lock = RwLock::new(10);

    {
        // ์ด๋ฎคํ„ฐ๋ธ”ํ•œ ์ฐธ์กฐ(reader)๋ฅผ ์–ป๋Š”๋‹ค.
        let v1 = lock.read().unwrap();
        let v2 = lock.read().unwrap();
        println!("{} {}", v1, v2); // ์ฝ๊ธฐ ๋™์ž‘
    }

    {
        v = lock.write().unwrap(); // ๋ฎคํ„ฐ๋ธ”ํ•œ ์ฐธ์กฐ(writer)๋ฅผ ์–ป๋Š”๋‹ค.
        *v = 7; // ์“ฐ๊ธฐ ๋™์ž‘
        println!("{}", v); // ์ฝ๊ธฐ ๋™์ž‘
    }
}

์ด ๋ฌธ์„œ๋ฅผ ์ธ์šฉํ•œ ๋ฌธ์„œ