[OS] Thread Safe

Jayยท2021๋…„ 2์›” 26์ผ
1

Computer Science

๋ชฉ๋ก ๋ณด๊ธฐ
22/50
post-thumbnail

Intro

๐Ÿ—บ Naver Map sdk๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๋„ํ™”๋ฉด์„ ๊ฐœ๋ฐœํ•˜๋˜ ์ค‘, Multithreading์„ ๋งŒ๋‚˜๊ฒŒ ๋˜์—ˆ๋‹ค.
์˜ˆ๋ฅผ๋“ค์–ด, ์ง€๋„์—์„œ ์นดํŽ˜๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ง€๋„ ์œ„์— ์นดํŽ˜ ๋งˆ์ปค๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ๊ทธ๋ ค์ง€๊ฒŒ ๋˜๋Š”๋ฐ ๋ญ 100๊ฐœ ์•ˆ์ชฝ์ด๋ฉด ๊ทธ๋ƒฅ ๊ทธ๋ ค์งˆ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.
๊ทผ๋ฐ ๋งŒ์•ฝ ์ด ๋งˆ์ปค๊ฐ€ 100๊ฐœ๋ฅผ ๋„˜์–ด์„œ 1000๊ฐœ.. ์ด๋ ‡๊ฒŒ ๊ฐ„๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?
"์นดํŽ˜" ๊ฒ€์ƒ‰๋งŒ ํ•˜๊ณ  ์ •๋ง ๋งŽ์€ ์‹œ๊ฐ„์„ ๋กœ๋”ฉ์„ ๊ธฐ๋‹ค๋ ค์•ผ ๋งˆ์ปค๊ฐ€ ๋‹ค ๊ทธ๋ ค์งˆ ๊ฒƒ ์ด๋‹ค.

Naver Map์—์„œ ๋งํ•˜๋Š” ์˜ค๋ฒ„๋ ˆ์ด ๊ฐ์ฒด๋Š” ์•„๋ฌด ์Šค๋ ˆ๋“œ์—์„œ๋‚˜ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์˜ค๋ฒ„๋ ˆ์ด ์†์„ฑ์€ ์Šค๋ ˆ๋“œ ์•ˆ์ •์„ฑ์ด ๋ณด์žฅ๋˜์ง€ ์•Š๊ธฐ์— ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋™์‹œ์— ์ ‘๊ทผํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.
โœ… ํŠนํžˆ, ์ง€๋„์— ์ถ”๊ฐ€๋œ ์˜ค๋ฒ„๋ ˆ์ด์˜ ์†์„ฑ์€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์ ‘๊ทผํ•ด์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด CalledFromWrongThreadException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

๋”ฐ๋ผ์„œ ์œ„์—์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋Œ€๋Ÿ‰์˜ ์˜ค๋ฒ„๋ ˆ์ด ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃจ ๊ฒฝ์šฐ, ๊ฐ์ฒด ์ƒ์„ฑ+์ดˆ๊ธฐ์˜ต์…˜ ์ž‘์—…์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ง€๋„์— ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…๋งŒ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํšจ์œจ์ ์ด๋‹ค.

์•„๋ž˜๋Š” ์˜ˆ์ œ ์ฝ”๋“œ์ด๋‹ค.

val executor: Executor = ...
val handler = Handler(Looper.getMainLooper())

executor.execute {
    // ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ
    val markers = mutableListOf<Marker>()

    repeat(1000) {
        markers += Marker().apply {
            position = ...
            icon = ...
            captionText = ...
        }
    }

    handler.post {
        // ๋ฉ”์ธ ์Šค๋ ˆ๋“œ
        markers.forEach { marker ->
            marker.map = naverMap
        }
    }
}

์ด๋ ‡๊ฒŒ Naver Map์—์„œ ์˜ค๋ฒ„๋ ˆ์ด ๊ฐ์ฒด ์„ค๋ช…์„ ๋ณด๋‹ค๊ฐ€ thread safeํ•œ ๊ฐœ๋ฐœ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์ด๋ฅผ ์ข€ ๋” ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.


Thread Safe

  • Multi-thread Programming์—์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋–ค ํ•จ์ˆ˜๋‚˜ ๋ณ€์ˆ˜, ํ˜น์€ ๊ฐ์ฒด๊ฐ€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ๋™์‹œ์— ์ ‘๊ทผ์ด ์ด๋ฃจ์–ด์ ธ๋„ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰์— ๋ฌธ์ œ๊ฐ€ ์—†์Œ์„ ๋œปํ•œ๋‹ค.
  • ํ•œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์ž‘ํ•ด๋„ ๋ฌธ์ œ์—†์ด ํ”„๋กœ๊ทธ๋žจ์ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ.
  • ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๊ฐ€ ํ•œ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ํ˜ธ์ถœ๋˜์„œ ์‹คํ–‰ ์ค‘์ผ ๋•Œ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋™์‹œ์— ํ•จ๊ป˜ ์‹คํ–‰๋˜๋”๋ผ๋„ ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ์˜ ํ•จ์ˆ˜์˜ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๊ฐ€ ์˜ฌ๋ฐ”๋กœ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

Thread๊ฐ€ Safeํ•˜์ง€ ์•Š๋‹ค?

์Šค๋ ˆ๋“œ๊ฐ€ safeํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋ผ๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ด ์žˆ์„๊นŒ?
ํ•ด๋‹น ๋ธ”๋กœ๊ทธ์— ์ข‹์€ ์˜ˆ์ œ๊ฐ€ ์žˆ์–ด์„œ ๊ฐ€์ ธ์™”๋‹ค.

์กฐํšŒ์ˆ˜ ๊ณ„์‚ฐ ํ”„๋กœ๊ทธ๋žจ

  • 100๋ช…์˜ ์Šค๋ ˆ๋“œ๋กœ ๊ฐ๊ฐ 100๋ฒˆ์„ ์กฐํšŒํ•  ๋•Œ
public class CountingTest {
    public static void main(String[] args) {
        Count count = new Count();
        for (int i = 0; i < 100; i++) {
            new Thread(){
                public void run(){
                    for (int j = 0; j < 100; j++) {
                        System.out.println(count.view());
                    }
                }
            }.start();
        }
    }
}
class Count {
    private int count;
    public int view() {return count++;}
    public int getCount() {return count;}
}

์œ„์˜ ์ฝ”๋“œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, 100๋ช…์˜ ์‚ฌ๋žŒ์ด ๊ฐ๊ฐ 100๋ฒˆ์”ฉ ์กฐํšŒํ•˜๊ณ  ์ด๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์‹œ์Šคํ…œ์ด๋‹ค.
๊ทธ๋Ÿผ ๋ฌด์กฐ๊ฑด 10000์ด ๋‚˜์™€์•ผ ํ•˜๋Š”๋ฐ
์ฐธ์กฐ:https://deveric.tistory.com/104

๊ฒฐ๊ณผ๋Š” ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๊ณ  ํ•œ๋‹ค.

์™œ?๐Ÿค”

count๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๋กœ์ง์€ 2๊ฐ€์ง€๋กœ ๋‚˜๋‰˜์–ด์ง„๋‹ค.
1. ๊ธฐ์กด์˜ count๋ฅผ ์ฝ์–ด์˜จ๋‹ค.
2. count์— +1์„ ํ•ด์„œ ๋‹ค์‹œ ์ €์žฅํ•œ๋‹ค.

1๋ฒˆ๊ณผ 2๋ฒˆ ์‚ฌ์ด์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ด€์—ฌํ•˜๊ฒŒ ๋˜๋ฉด
๋‚˜๋Š” 22๋ฅผ ๊ฐ€์ ธ์™€์„œ 23์„ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ
๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋„ 22๋ฅผ ๊ฐ€์ ธ์™€์„œ 23์„ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค.
๊ทธ๋Ÿผ ์ผ๋‹จ ์œ„์˜ ํ•œ ๊ฒฝ์šฐ๋งŒ ์ƒ๊ฐํ•ด๋„ ์ตœ์ข…์ ์œผ๋กœ 9999๊ฐ€ ๋‚˜์˜ฌ๊ฒƒ์ด๋‹ค..
์šฐ๋ฆฐ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋‹ค. ์Šค๋ ˆ๋“œ๊ฐ€ ์–ธ์ œ ๋™์‹œ์— ์ ‘๊ทผํ•ด์„œ ์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ• ์ง€ ๐Ÿ˜ญ


๋™์‹œ์„ฑ์„ ์ œ์–ดํ•˜๋Š” ๋ฐฉ๋ฒ•

์•”์‹œ์  Lock

๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๋ฉด์„œ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ Lock์„ ๊ฑธ์–ด ๋ฒ„๋ฆฌ๋Š” ๊ฒƒ.
Lock์ด ์ ์šฉ๋˜๋ฉด ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ ์ค‘์ผ ๋• ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋Œ€๊ธฐํ•˜๊ฒŒ ๋œ๋‹ค.
1๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ๋ง‰์„ ์ˆœ ์žˆ์ง€๋งŒ ๋ณ‘๋ ฌ์„ฑ์€ ๋งค์šฐ ๋‚ฎ์•„์ง„๋‹ค.๐Ÿ˜ซ

๐Ÿ– ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ๊นŒ?
๋ฌธ์ œ๊ฐ€ ๋œ view๋ฉ”์„œ๋“œ์— synchronized ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด๋ฉด ์•”์‹œ์  ๋ฝ์ด ๊ฑธ๋ฆฐ๋‹ค.

  • lock์€ ๋ฉ”์„œ๋“œ, ๋ณ€์ˆ˜์— ๊ฐ๊ฐ ๊ฑธ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฉ”์„œ๋“œ์— lock์„ ๊ฑธ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฉ”์„œ๋“œ์— ์ง„์ž…ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ๋‹จ ํ•˜๋‚˜์ด๋‹ค.
  • ๋ณ€์ˆ˜์— lock์„ ๊ฑธ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ณ€์ˆ˜์— lock์„ ๊ฑธ๊ธฐ ์œ„ํ•ด์„  ๋ฐ˜๋“œ์‹œ ํ•ด๋‹น ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒด์—ฌ์•ผ ํ•˜๋ฉฐ int, long๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธํ˜• ํƒ€์ž…์—๋Š” lock์„ ๊ฑธ ์ˆ˜ ์—†๋‹ค.

Method Lock

class Count {
    private int count;
    public synchronized int view() {return count++;}
}

๋ณ€์ˆ˜ Lock

class Count {
    private Integer count = 0;
    public int view() {
        synchronized (this.count) {
            return count++;
        }
    }
}

๋ช…์‹œ์  Lock

synchronized ํ‚ค์›Œ๋“œ ์—†์ด ๋ช…์‹œ์ ์œผ๋กœ ReentrantLock์„ ์‚ฌ์šฉํ•˜๋Š” Lock.

  • Lock์˜ ๋ฒ”์œ„๋ฅผ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ํ•œ์ •ํ•˜๊ธฐ ์–ด๋ ต๊ฑฐ๋‚˜, ๋™์‹œ์— ์—ฌ๋Ÿฌ lock์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋–„ ์‚ฌ์šฉํ•œ๋‹ค.
  • Lock๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • lock()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น lock() ๋ฉ”์„œ๋“œ ์‹œ์ž‘์ ์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋Œ€๊ธฐํ•œ๋‹ค. unlock()์„ ์‹คํ–‰ํ•ด์•ผ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ lock์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.
public class CountingTest {
    public static void main(String[] args) {
        Count count = new Count();
        for (int i = 0; i < 100; i++) {
            new Thread(){
                public void run(){
                    for (int j = 0; j < 1000; j++) {
                        count.getLock().lock();
                        System.out.println(count.view());
                        count.getLock().unlock();
                    }
                }
            }.start();
        }
    }
}
class Count {
    private int count = 0;
    private Lock lock = new ReentrantLock();
    public int view() {
            return count++;
    }
    public Lock getLock(){
        return lock;
    };
}

์œ„์™€ ๊ฐ™์ด Thread-Safe๋ฅผ ์ง€ํ‚ค๋Š”๋ฐ๋Š” 5๊ฐ€์ง€ ์›์น™์ด ์žˆ๋‹ค.

1. Re-entrancy

  • ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ํ•œ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰ ์ค‘์ผ๋•Œ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋”๋ผ๋„ ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ๊ฐ์—๊ฒŒ ์˜ฌ๋ฐ”๋กœ ์ฃผ์–ด์ ธ์•ผํ•œ๋‹ค.
  • Aํ•จ์ˆ˜ ์‹คํ–‰ ์ค‘, Bํ•จ์ˆ˜ ์‹คํ–‰ ์‹œํ‚ค๋”๋ผ๋„ A,B๋Š” ๊ฐ๊ฐ ์ž์‹ ์˜ ์ผ์„ ์˜ฌ๋ฐ”๋กœ ์ˆ˜ํ–‰ํ•˜๋Š”๊ฒŒ ๋‹น์—ฐํ•˜๋‹ค.

2. Thread-local storage

  • ๊ณต์œ  ์ž์›์˜ ์‚ฌ์šฉ์„ ์ตœ๋Œ€ํ•œ ์ค„์—ฌ ๊ฐ๊ฐ์˜ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ €์žฅ์†Œ๋“ค์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋™์‹œ ์ ‘๊ทผ์„ ๋ง‰๋Š”๋‹ค.
  • ์ด ๋ฐฉ์‹์€ ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•๊ณผ ์—ฐ๊ด€ ์žˆ๊ณ  ๋˜ํ•œ ๊ณต์œ ์ƒํƒœ๋ฅผ ํ”ผํ•  ์ˆ˜ ์—†์„๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

3. Mutual exclustion

  • Thread์— lock์ด๋‚˜ semaphore๋ฅผ ๊ฑธ์–ด์„œ ๊ณต์œ ์ž์›์—๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.

4. Atomic operation

  • ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‹œ, atomicํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค.

Atomic
: ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ๋™์‹œ์— ์ผ์–ด๋‚œ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ฒƒ.
๋ฐ์ดํ„ฐ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๊ธฐ์— atomicํ•œ ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์ด๋ฃจ์–ด์ง€๋Š” ์‹œ๊ฐ„์—๋Š” lock์„ ๊ฑด๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์‹œ๊ฐ„๋™์•ˆ ์ ‘๊ทผ์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

5. Immutable Object

  • ๊ฐ์ฒด ์ƒ์„ฑ ์ดํ›„์— ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋„๋ก ๋งŒ๋“ ๋‹ค.

์Šค๋ ˆ๋“œ ๋™๊ธฐํ™”

A,B๊ฐ€ ๋™์‹œ์— ์‹คํ–‰ ๋  ๋•Œ, ๋™์‹œ ์ ‘๊ทผ์ด ์•ˆ๋˜๊ธฐ์— ์‹คํ–‰ ์ˆœ์„œ ํ˜น์€ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์— ๋Œ€ํ•ด์„œ ๋™๊ธฐํ™”๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค. (๊ด€์ ์— ๋”ฐ๋ผ 2๊ฐœ๋กœ ๋‚˜๋‰˜์–ด์ง„๋‹ค)

- ์‹คํ–‰ ์ˆœ์„œ์˜ ๋™๊ธฐํ™”

: ์Šค๋ ˆ๋“œ์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•˜๊ณ , ๋ฐ˜๋“œ์‹œ ์ด ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅด๋„๋ก ํ•œ๋‹ค.

- ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์— ๋Œ€ํ•œ ๋™๊ธฐํ™”

: ๋ฐ์ดํ„ฐ ์˜์—ญ๊ณผ ํž™ ์˜์—ญ๊ณผ ๊ฐ™์ด ํ•œ ์ˆœ๊ฐ„์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์— ๋Œ€ํ•œ ๋™๊ธฐํ™”.
: ๋งŒ์•ฝ 2๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๋ฐ์ดํ„ฐ ์ ‘๊ทผํ•˜์—ฌ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ๋ฎ์—ฌ์”Œ์›Œ์ง€๋Š” ์—ฌ๋Ÿฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.


๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๋ฐฉ๋ฒ•

์œ ์ €๋ชจ๋“œ ๋™๊ธฐํ™”

  • User Mode Synchonize
  • ๋™๊ธฐํ™”๊ฐ€ ์ง„ํ–‰๋˜๋Š” ๊ณผ์ •์—์„œ ์ปค๋„์˜ ํž˜์„ ๋นŒ๋ฆฌ์ง€ ์•Š๋Š”(์ปค๋„ ์ฝ”๋“œ ์‹คํ–‰X) ๋™๊ธฐํ™” ๊ธฐ๋ฒ•
  • ๋”ฐ๋ผ์„œ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด์„œ ์ปค๋„ ๋ชจ๋“œ๋กœ์˜ ์ „ํ™˜์ด ๋ถˆํ•„์š”ํ•ด์„œ ์„ฑ๋Šฅ์ƒ ์ด์ .
  • ๊ทธ๋งŒํผ ๊ธฐ๋Šฅ ์ œํ•œ๋„ ์žˆ๋‹ค.
    ex) critical section ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”, inter-lock ํ•จ์ˆ˜ ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”

์ปค๋„๋ชจ๋“œ ๋™๊ธฐํ™”

  • Kernal Mode Synchronize
  • ์ปค๋„์—์„œ ์ œ๊ณตํ•˜๋Š” ๋™๊ธฐํ™” ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ๋™๊ธฐํ™” ๊ด€๋ จ๋œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ปค๋„ ๋ชจ๋“œ๋กœ์˜ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜๊ณ , ์ด๋Š” ์„ฑ๋Šฅ์˜ ์ €ํ•˜๋กœ ์ด์–ด์ง„๋‹ค.
  • ํ•˜์ง€๋งŒ ๊ทธ๋งŒํผ ์œ ์ € ๋ชจ๋“œ ๋™๊ธฐํ™”์—์„œ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
    ex) ๋ฎคํ…์Šค ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”, ์„ธ๋งˆํฌ์–ด ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”, ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™”

volatile

์Šค๋ ˆ๋“œ์™€ ๋™์‹œ์„ฑ์„ ์ด์•ผ๊ธฐํ•˜๋‹ค๋ณด๋ฉด volatile ์ด์•ผ๊ธฐ๋„ ๋‚˜์˜จ๋‹ค.
์œ„์—์„œ ์ฃผ๊ตฌ์žฅ์ฐฝ ์ด์•ผ๊ธฐ ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผ์„ ํ•  ๋•Œ ์ด๋ฅผ ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ์ ‘๊ทผ์‹œํ‚ค๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋งค์šฐ ๋งŽ์ด ๋‚˜๊ณ  ์›์น˜ ์•Š๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ thread-safeํ•˜๊ฒŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๋Š”๊ฒŒ ์ค‘์š”ํ•˜๋‹ค๊ณ  ํ–ˆ๋‹ค.

๊ทผ๋ฐ ๊ทธ๋ ‡๋‹ค๋ฉด ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ• ๊นŒ?
์ •๋‹ต์€ ์•„๋‹ˆ๋‹ค. CPU์บ์‹œ์— ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ๋„ ํ•œ๋‹ค.
๊ทธ๋ž˜์„œ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ์‹ค์ œ ๋ฐ์ดํ„ฐ์™€ ํ•ญ์ƒ ์ผ์น˜ํ• ์ง€ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•œ๋‹ค.
๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ €์žฅ๋œ ์‹ค์ œ ์ž์›์˜ ๊ฐ’์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋…์„ ์ž์›์˜ ๊ฐ€์‹œ์„ฑ์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ ์ด๋ฅผ ์ถฉ์กฑ์‹œํ‚ค์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ๋‹ค.

volatile์€ CPU ์บ์‹œ ์‚ฌ์šฉ์„ ๋ง‰๋Š”๋‹ค. ํ‚ค์›Œ๋“œ๋กœ ๋ถ™๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋Š” ์บ์‹œ์— ์ €์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด ๋งค๋ฒˆ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ๋‹ค.

๊ทธ๋ž˜์„œ volatile์€ ์ž์›์˜ ๊ฐ€์‹œ์„ฑ์€ ํ™•๋ณดํ•ด์ฃผ์ง€๋งŒ ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ์—” ๋ถ€์กฑํ•˜๋‹ค. read&write ์‹œ์ ์— ๋™๊ธฐํ™”๋ฅผ ํ•  ๋•Œ ํ•ด๋‹น ์—ฐ์‚ฐ์ด ์›์ž์„ฑ์„ ์ด๋ฃจ๋„๋ก ์„ค์ •ํ•ด์ค˜์•ผ ๋น„๋กœ์†Œ ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ– volatile์€ ์‚ฌ์šฉํ•ด์•ผ ์ข‹์„๊นŒ?

2๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ๊ณ  ํ•œ ์Šค๋ ˆ๋“œ๋Š” read๋งŒ, ํ•œ ์Šค๋ ˆ๋“œ๋Š” write๋งŒ ํ•  ๊ฒฝ์šฐ.
read๋งŒ ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” cpu์บ์‹œ์—์„œ ๊ฐ’์„ ํ™•์ธํ• ํ…๋ฐ write๋งŒ ํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋„ฃ์€ ๊ฐ’์„ ๋ฐ”๋กœ ํ™•์ธํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค.
์ด๋Ÿด ๊ฒฝ์šฐ, volatile์„ ๋ถ™์—ฌ ๋‘ ์Šค๋ ˆ๋“œ๊ฐ€ ์“ฐ๊ณ  ์ฝ๋Š” ๊ฐ’์˜ ์›์ž์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ๋‹ค. ๋™์‹œ์„ฑ ์ด์Šˆ ์—ญ์‹œ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

โŒ CPU์บ์‹œ๋ฅผ ๋น„ํ™œ์„ฑํ™” ํ•˜๊ณ  ๋งค๋ฒˆ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ธฐ์— ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋‹น์—ฐํžˆ ๋ฐœ์ƒํ•˜๊ธฐ์— ์œ ์˜ํ•ด์„œ volatile์„ ์จ์•ผํ•œ๋‹ค.

Reference

profile
developer

0๊ฐœ์˜ ๋Œ“๊ธ€