모니터가 어떻게 동기화에 사용되는지 아주 자세히 설명합니다! 자바에서 모니터는 어떤 모습인지도 설명하니 헷갈리시는 분들 꼭 보세요!

Sdílet
Vložit
  • čas přidán 4. 07. 2024
  • #모니터 #동기화 #자바 #monitor #synchronization #java
    대표적인 동기화 툴인 모니터!
    프로그래밍 언어 레벨에서 이 모니터를 많이들 지원하는데요,
    모니터가 어떻게 동작하는지 그 원리를 아주 자세히 설명합니다!
    bounded producer/consumer problem도 모니터로 어떻게 해결하는지 알려드리구요!!
    얼마나 친절히 설명하는지 무려 27분짜리 영상입니다!!!
    게다가!! 자바에서는 모니터를 어떻게 사용하는지도 살펴봅니다!
    헷갈리시는 분들 꼭 보세요!
    00:00 오프닝
    00:15 모니터(monitor)란?
    00:25 모니터는 언제 사용?
    00:41 모니터 구성 요소: mutex, condition variable
    02:28 모니터 뼈대 살펴보기
    07:29 모니터에 존재하는 두 가지 큐(queue)
    07:53 예제로 살펴보는 모니터(컨슈머 프로듀서 문제)
    21:15 자바로 모니터 살펴보기 (예제 포함)
    26:41 자바 동기화 관련 참고 사항
    27:01 클로징
  • Věda a technologie

Komentáře • 42

  • @ez.
    @ez.  Před 2 lety +1

    중간 중간 목 상태가 좋지 않아요 ㅠㅠ
    양해 부탁드립니다아~
    영상에서 예제들은 주로 위키( en.wikipedia.org/wiki/Monitor_(synchronization) )에 있는 예제를 사용했습니다.
    자바에서 두 개 이상의 condition variable을 사용하는 예제는 여기( docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/locks/Condition.html ) 참고해주세요,

  • @minjoon1324
    @minjoon1324 Před 8 měsíci

    역대급이군요 감사합니다..

  • @user-qo7ni8bz4t
    @user-qo7ni8bz4t Před rokem

    최고십니다 ! 고퀄 영상 찍어주셔서 감사합니다

    • @ez.
      @ez.  Před rokem

      감사합니다!! 자주 놀러와 주세요~ 고퀄 영상 많이 준비해 놓을게요 👍

  • @growie000
    @growie000 Před rokem

    덕분에 이해 잘 됐습니다. 감사합니다 !

    • @ez.
      @ez.  Před rokem

      역시 성장캐릭터십니다!! 👍

  • @user-ht4pt6lh4y
    @user-ht4pt6lh4y Před rokem

    준비하신 자료도 너무 깔끔하고 설명도 자세하게 해주셔서 이해가 쏙쏙 됐어요! 좋은 자료 만들어주셔서 감사합니다~ 잘보고 있어요!

    • @ez.
      @ez.  Před rokem

      크~ 특급 칭찬 감사합니다!! 유익하게 봐주셔서 저도 정말 감사해용 :)
      앞으로도 잘 부탁드립니다! 자주 자주 들러주세요~~ 👍👍

  • @woolee7205
    @woolee7205 Před rokem

    군더더기 없는 깔끔한 설명과 적절한 예제로 아주 이해하기 좋습니다 항상 잘 보고 있어요 감사합니다

    • @ez.
      @ez.  Před rokem

      칭찬 감사합니다 🥹
      모니터 영상은 꽤 시간을 많이 썼던 영상인데 도움이 된 것 같아서 뿌듯하네요 ㅎㅎ
      늘 애청해주셔서 감사합니다 👍👍

  • @user-kq1de9ef2t
    @user-kq1de9ef2t Před rokem

    와 모니터 이렇게 자세히 설명하는 영상은 처음이네요! 많은 도움 받고 갑니다

    • @ez.
      @ez.  Před rokem

      알차게 준비하는데 고생을 좀 했었죠 ㅎㅎ
      도움이 된 것 같아서 저도 뿌듯하네요 :)
      댓글 감사합니당 👍

  • @thwn40
    @thwn40 Před rokem +1

    설명 정말 맛있습니다

    • @ez.
      @ez.  Před rokem

      안녕하세요 미쉐린 가이드에 선정된 쉬운코드 입니다 🤣

  • @doxxx93
    @doxxx93 Před 2 lety +2

    와.. 공부하다 흘러흘러 이곳까지 오게되었는데 정말 설명이 야무지게 되어있네요

    • @ez.
      @ez.  Před 2 lety +1

      크~~ 칭찬 감사합니다~!! 야무진 영상들 많이 있어요!!ㅎㅎ 자주자주 들러주세요 :)

  • @LeeMyeongjae
    @LeeMyeongjae Před 2 lety +1

    와 잘 배웠습니다.!!

    • @ez.
      @ez.  Před 2 lety +2

      응원합니다~! 앞으로도 좋은 영상으로 계속 찾아뵐게요 :)

  • @solovelystarlight
    @solovelystarlight Před 2 lety +1

    백엔드 개발자 준비 중인데, 필요한 내용을 이해하기 쉽게 설명해 주시는 덕분에 많은 도움이 됩니다:) 좋은 강의 영상 공유해 주셔서 고맙습니다!!

    • @ez.
      @ez.  Před 2 lety +3

      우와~ 많은 도움이 된다고 말씀해주시니까 저도 뿌듯하고 좋네요 :) 앞으로도 좋은 영상 많이 많이 공유하겠습니다!! 구독자님 응원합니다!!!

  • @jerryk0269
    @jerryk0269 Před rokem +4

    이번 내용은 조금 어려운 내용이네요! 덕분에 추상적으로 알고 있던 지식들을 조금 더 명확하고, 생각 없이 쓰던 자바의 스레드 wait에 대해서도 훨씬 명확히 알 수 있게 되었고, 저만의 언어로 정의할 수 있게 된 것 같네요 감사합니다!!
    이때 컨디션 많이 안 좋으셨던 것 같은데 도움이 정말 많이 되었습니다!!! (마지막에 너무 피곤한 목소리라 마음 아팠네요 🥲)
    monitor : mutual exclusion을 보장, 조건에 따라 스레드가 대기 상태로 전환하는 기능을 가진다. 여러 스레드와 협업하거나, 한 번에 하나의 작업만 필요할 때 사용된다. 모니터는 mutex와 condition variable로 이루어진다.
    mutex lock을 쥔 스레드가 lock을 반환하면, 큐에서 대기 상태로 대기하던 스레드 중 하나가 실행되면 critical section에 진입한다.
    condition variable : waiting queue를 가진다.
    - waiting queue : critical section에 진입하고 싶어하는 스레드들이 mutex lock을 받기 위해 대기하는 공간. condition variable에서 관리한다.
    - wait : 스레드가 "자기 자신을" waiting queue에 넣고 대기 상태로 전환한다.
    - signal : waiting queue에서 대기중인 스레드의 "하나"를 깨운다. (아마 pop 혹은 인자로 받은 스레드 탐색)
    - broadcast : waiting queue에서 대기중인 스레드 "전부"를 깨운다.
    vs
    entry queue : critical section에 진입을 기다리는 큐. mutex에서 기대하는 락이 없으면 해당 스레드를 강제로 집어넣는다.
    => entry queue 같은 경우는 좀더 system level의 lock이고, waiting queue 같은 경우에는 비즈니스 로직과 연관된 user level의 custom한 lock이라는 생각이 드네요
    이 queue들은 priority queue
    대기 상태로 들어갈 때는 mutex lock을 쥐어선 안 되기 때문에 반환되어야 한다
    bounded producer / consumer problem : producer는 buffer가 가득찼을 때 언제 자리가 나는지 계속 들여다 보아야 하는가? consumer는 buffer가 비어있을 때 언제 값이 들어있는지 계속 들여다 보아야 하는가?
    - monitor를 활용하면 IO 대기상태일 때 재우고, 원하는 값이 들어있을 때 상대에서 인터럽트를 보내서 효율적인 개발이 가능해진다. 즉, spin lock 방식이 아닌 event driven 방식으로 개발할 수 있게 된다.
    - signal and continue : 상대를 깨운 뒤 자신도 병렬적으로 실행 (non-blocking)
    - signal and wait : 상대를 깨우고 상대가 release할 때까지 대기한 후 마저 실행 (blocking)
    대기에서 깨어났을 때는 이전에 만족하던 조건이 현재도 만족한다는 보장이 없다 (ex. lock)
    - 따라서 wait는 while에 넣고 조건을 계속 확인하는 것이 중요하다!
    java에서 mutual exclusion은 synchronized 키워드로 사용이 가능하며, monitor는 condition variable을 하나만 가진다.
    => condition variable이 하나만 존재하기 때문에 복잡성이 조금 더 줄어든 느낌이네요. 대신 메인 스레드에서 여러 목적의 waiting queue를 활용하지는 말라고 지시하는 느낌?도 들고요. (여러 목적의 스레드를 한 waiting queue에서 작업하면 heap이 가지는 우선순위의 장점을 크게 못살리는 느낌이 들어서요)
    java monitor 3가지 동작
    - wait / notify(signal) / notifyAll(broadcast)

    • @ez.
      @ez.  Před rokem

      감사합니다 ㅠㅠ 이날이 아마 제가 새벽에 영상을 찍어서 목이 잠겨서 더 그랬던것 같아요 ㅎㅎ 마음 써주셔서 감동입니다 ㅠㅠ
      그리고 오늘도 멋진 정리 정말 최고십니다!! 👍👍👍
      정리하신 내용 중에서 일부는 의미를 조금 더 정확히 하는 게 이해하실 때 더 많이 도움 될 것 같아서 몇 가지 코멘트 남깁니다 :)
      ---
      >> waiting queue : critical section에 진입하고 싶어하는 스레드들이 mutex lock을 받기 위해 대기하는 공간. condition variable에서 관리한다.
      라고 정리하게 되면 entry queue와 개념이 헷갈릴 수 있어요~ 왜냐하면 'mutex lock을 받기 위해 대기하는 공간'은 실제로는 entry queue라서요~ 그래서 개인적으로는 'condition variable이 관리하는 queue로서 특정 조건을 만족할 때까지 대기하는 queue'라고 이해하는게 더 좋을 것 같아요~
      >> 이 queue들은 priority queue
      말씀하신 것처럼 priority queue일수도 있고요, 랜덤 queue일 수도 있어서, 구현에 따라 다를 수 있다고 이해하시면 더 좋을 것 같습니다 :)
      >> signal and continue : 상대를 깨운 뒤 자신도 병렬적으로 실행 (non-blocking)
      병렬로 실행된다는 표현은 듣기에 따라서는 '깨어난 스레드도 동시에 critical section에서 마저 실행된다는 것인가'로 이해될 수 있어서 개인적으로는 '깨운 스레드는 그 이후의 코드를 계속해서 실행하고, 깨어난 스레드는 entry queue로 들어간다'라고 정리하는게 더 정확할 것 같아요~
      >> condition variable이 하나만 존재하기 때문에 복잡성이 조금 더 줄어든 느낌이네요.
      맞습니다 👍 기본적으로 제공되는 자바의 모니터락은 단순화를 위해 그렇게 한 것 같아요
      좀 더 복잡한 경우에는 직접 모니터를 구현해서 사용해야 되는 듯 하고요
      이와 관련해서 참고할 만한 코드를 아래에 남겨드립니다 :)
      docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html

  • @CodingASMR-zv2vp
    @CodingASMR-zv2vp Před měsícem

    안녕하세요 쉬운코드님 영상 너무 잘 보고 있습니다 ㅎㅎ
    영상을 보다가 궁금한 점이 하나 생겼습니다
    signal & continue 방식과 signal & wait 방식 2가지를 설명해 주셨는데
    signal wait 상태로 동작을 한다고 하면
    기존의 condition variable인 emptyCV와 fullCV가 아닌 다른 형태의 condition variable이 있고
    해당 condition variable의 wating queue에 넣어주는 방식으로 동작을 할까요?

  • @deniapark761
    @deniapark761 Před rokem

    요즘 쉬운코드님 영상들을 다시 정주행 하면서 하나 궁금증이 생겼습니다.
    저번 영상에서 나온 세마포어 와 모니터가 혹시 어떻게 다른건지 몇가지 차이점을 말씀해주실 수 있으실까요 ?
    제 머리로는 아무래도 비슷한거 같은데 어떻게 다른지 잘 느낌이 오지 않습니다 ㅠㅠ
    그리고 항상 잘보고 있습니다.
    응원합니다!

    • @ez.
      @ez.  Před rokem

      앗 그러셨군요~! 제가 이걸 말씀드릴 수도 있는데요, 이 경우는 오픈 퀘스천으로 남겨놓을게요~
      아무래도 이런 종류의 질문은 제가 답변드리는 것 보다는 스스로의 힘으로 고민하고 소화하려고 노력할 때 생각의 힘과 폭이 더 성장할 수 있다고 생각하거든요~
      그래서 이 부분은 이해를 부탁드리겠습니다 :)
      저도 denia park님의 성장을 응원합니다~!! 힘힘힘!! 💪💪💪

  • @chupinadventure
    @chupinadventure Před 7 měsíci

    GOAT

  • @kkssrcn
    @kkssrcn Před 2 lety +2

    영상 잘봤습니다. 설명 너무 잘하시네요 ㅎㅎ
    한가지 궁금한점이 있는데요. 뮤텍스 락이 해제 될때 entry queue에 있는 스레드중에 하나를 깨운다고 하셨는데 이때 일어난 스레드가 뮤텍스 락을 얻기 전에 새롭게 진입한 다른 스레드가 락을 가로챌수도 있나요?
    그렇게 되면 entry queue에서 일어난 스레드가 다시 entry queue로 들어갈것 같네요.

    • @ez.
      @ez.  Před 2 lety +1

      흐흐 먼저 칭찬해주셔서 감사합니다 👍
      매끄럽게 영상을 만들려고 노력하다보니 편집을 열심히 해서 더 그렇게 보이는거 같아요ㅎㅎ
      질문주신 내용에 대해서 (OS 마다, 그리고 언어마다 다를 수 있기 때문에 100%라고 말하지는 못하겠지만 일반적인 수준에서)
      답변을 드리면
      맞습니다~! 질문 주신 내용은 말씀하신 대로 동작합니다. 새롭게 진입한 다른 스레드가 락을 가로챌 수 있어요.
      조금 더 큰 그림으로 일반적인 차원에서 시나리오를 말씀드리자면,
      모니터의 뮤텍스 락에서 관리되는 queue(모니터에서는 entry queue 혹은 entry set이라고 부르는 queue)에서 깨어난 스레드 A는 cpu에서 이어서 실행되기 위해 OS에서 관리하는 ready queue에서 대기하게 됩니다.
      하지만 만약에 새로운 스레드 B가 모니터의 뮤텍스 락을 취득하기 직전의 상태로 ready queue에서 대기하고 있었다면, 이 때 OS 스케줄러가 어떤 선택을 하는지에 따라 스레드 A가 아니라 스레드 B가 먼저 CPU에서 실행될 수 있고, 그럼 B가 모니터의 뮤텍스 락을 취득하고 실행하게 됩니다.
      결국 A가 CPU에서 실행됐을 때는 B가 모니터의 뮤텍스 락을 취득한 상태이기 때문에 다시 모니터의 entry queue에 들어가게 되지요.
      말씀하신 것이 정확히 맞습니다 :)

  • @ohtaeg
    @ohtaeg Před rokem

    이번에도 좋은 영상 감사드리며 궁금한 점이 있어서 질문 드리는 점 죄송합니다 ㅠㅠ
    2:35 부터 설명해주시는 sudo 코드에서 두가지 궁금한 점이 있습니다..!
    (T1, T2 - 스레드)
    1. T1이 lock을 획득하여 critical section에 진입
    2. T2가 진입하려는데 모니터 락을 소유한 스레드가 이미 있어서 Entry Queue에 대기
    3. T1이 lock을 반환하기 위해 signal()을 호출
    Q1.이때 waiting queue에 대기하고 있는 스레드가 없으면 signal() 함수는 호출하지 않는건지
    혹은 signal()을 호출하고 대기하고 있는 스레드가 없으면 Entry Queue에서 대기하고 있는 스레드를 깨우는 걸까요?
    Q2. 다른 블로그들에서 일부는 signal()로 waiting queue에 있는 스레드가 깨어나면 모니터 락 획득을 위해
    다시 Entry Queue로 들어간다고 하는데 다시 Entry Queue로 들어가는게 맞는지 궁금합니다..!
    질문이 많아서 죄송하며, 쉬운코드님 덕분에 두려웠던 락을 조금씩 이해하면서 공부하게 되었습니다!!
    감사합니다 😄

    • @ez.
      @ez.  Před rokem +2

      안녕하세요 :) 늘 영상을 유익하게 봐주셔서 감사합니다~!!ㅎㅎ
      열심히 하시는 모습 멋지십니다~! 분명히 계속해서 성장하시게 될 거예요 :) 👍
      답변드리자면,
      Q1. 함수 호출이 명시적으로 적혀있기 때문에 호출은 항상 될 거고요, 함수 내부 구현에서 waiting queue를 확인할 할텐데 아무것도 없으면 그냥 그 함수 호출은 끝나게 될 것 같습니다
      Q2. signal한 뒤에 어떻게 되는지는 두 가지로 나뉘고요, 영상에서는 그 중에서 signal and continue 방식으로 설명을 드렸었습니다
      이 방식에서는 waiting queue에서 깨어난 스레드가 entry queue로 들어가게 됩니다
      15:17 부분 근처를 보시면 될 것 같아요 :)

    • @ohtaeg
      @ohtaeg Před rokem

      @@ez.
      꼼꼼하게 답변 주셔서 감사합니다 !! :) 👍

  • @weyoung1346
    @weyoung1346 Před rokem

    정말 좋은 영상입니다 ㅠㅠ 몇 번을 봐도 아깝지가 않네요! 그 전 강의에 이어 이 영상도 같이 시청하니 이해도가 높아진 것 같습니다!
    정말 죄송하게도.. 이번 영상 시청 후에도 질문이 생겼는데요..
    1 ) 영상 중 bounded producer / consumer 예시에서 entry queue가 구현 방법에 따라서 반드시 선입선출이 아니라고 설명해 주셨습니다! 그 얘기는 모니터를 사용하는 방식은 상호 배제는 보장할 수 있지만, 차례대로 순서가 보장되어야 할 필요가 있는 경우에는 적합하지 않다는 의미로 해석해도 될까요??.. 이 경우에는 세마포어를 사용하는 것이 맞겠죠?..
    2 ) 같은 예시에서 스레드가 대기 상태로 전환이 되었다가 다시 실행이 될 때 , 그 전 실행에 이어 코드를 실행하는 것으로 이해했는데,
    이 부분은 thread 별로 가지고 있는 PC 때문에 가능한 부분일까요??
    영상 너무 잘 봤습니다ㅠㅠ.. 예시가 너무 쉬워서 잘 와닿습니다!! 항상 양질의 영상 감사합니다 ㅎㅎ !!

    • @ez.
      @ez.  Před rokem

      언제나 좋은 말씀과 칭찬 감사합니다 :)
      1) 혹시 영상 몇분 몇초인지 알려주실 수 있을까요? ㅠ 제가 영상을 계속 찍다보니 정확히 어떤 의미로 했는지 기억이 잘 나지 않아서요 ㅠ
      제 기억이 맞다면, entry queue 이름에 queue가 들어가 있으니까 선입선출로 생각하기 쉬운데 큐도 여러 종류가 있기 때문에 가령 priority queue 일 수도 있어서 한 말이 아니었을까 짐작해 봅니다
      2) 네 맞숩니당 👍
      열심히 공부하시는 모습 멋지십니다!! 항상 응원합니다 화이팅!!!

    • @weyoung1346
      @weyoung1346 Před rokem

      @@ez. 안녕하세요! 1) 17:21 초 즈음의 내용입니다! 답변 주신걸 확인하고 다시 내용을 보니 제가 잘못 생각했던 것 같습니다 ㅎㅎ 정정 감사드립니다~
      혹시 예시로 나온 Thread.join()에 대해 여쭤봐도 될까요??..
      join() 내부에 구현이
      if(is_alive()){
      wait(0)
      }
      이런 식으로 되어있던데,
      만약 메인 스레드가 thread1.join()을 호출한다면
      thread1이 코드를 진행 중인 상태일때 메인 스레드는 wait 상태가 되잖아요??
      그런데 wait(0) == wait()이라서 thread1 스레드가 노티해주지 않으면
      main 스레드는 계속 waiting 상태라고 하더라구요..
      그런데 주석을 읽어보니 thread1.interrupt() 가 되면, thread1이 종료되고,
      thread1의 wait set이 사라져 그 안에서 대기 중이었던 main thread가 다시 scheduling이 가능한 상태로 바뀐다고 이해하였습니다!
      혹시 위 내용이 맞을까요???

    • @ez.
      @ez.  Před rokem

      오 넵 확인 감사합니다 :)

  • @user-sf8mp8qo7h
    @user-sf8mp8qo7h Před 2 lety

    한번 시청 : 음....50%도 이해가...일단 이런 기능이 구체적으로 어떤 경우에 사용되는지 잘 모르겠습니다.
    예를 들어 주신 producer , consumer 까지는 끄떡 끄떡 하겠는데, 실체가 전혀 감이 안옵니다.
    절반도 이해가 안되는 상황이라 이게 세마포어 인지, 뮤텍스 인지도 헷갈립니다.
    여러번 봐야 겠습니다. ㅠㅠ
    감사합니다.

    • @user-sf8mp8qo7h
      @user-sf8mp8qo7h Před 2 lety

      두번 시청
      큐가 두개가 있다
      엔트리 큐: 크리티컬 섹션에 들어 가기위한 mutex lock 을 얻을때 까지 대기
      웨이팅 큐: 원하는 조건이 충족 될때 까지 대기 하는 장소 condition variable
      이거랑 세마포어랑 뭐가 다른가요?
      사용하는 이유 한번에 하나의 스래드만 동작하길 원할때 또는 스래드간 협업이 필요할때
      실제로 어떻게 쓰는지는 모르겠어요 하하
      그래도 두번 보니 뭘 모르겠는지는 알겠습니다.
      오늘도 감사합니다.

    • @ez.
      @ez.  Před 2 lety +1

      크 오늘도 멋지게 달리시고 계시군요~!! 갈가마구님 최고십니다!
      모니터의 주요 특징 두 가지 때문에 영상을 만든 것인데요,
      1. 모니터는 동기화 관련해서 두 가지 좋은 기능을 제공합니다
      첫째는는 모니터는 critical section을 보장합니다. 둘째는 그리고 critical section 내에서 작업을 하다가 어떤 특정 조건이 만족할 때 까지 waiting하고 싶을 때 waiting할 수 있는 기능 또한 제공합니다. critical section 내에서 waiting 하는 기능은 뮤텍스나 세마포는 제공하지 않는 기능이죠
      2. 대표적으로 자바가 모니터를 사용합니다.
      우리나라 IT 환경에서는 여전히 자바가 주류라서 모니터를 다룰 필요성이 있겠다 싶었습니다.
      그래서 영상 말미에 자바를 소개한 것은 모든 자바 객체는 모니터를 하나씩 들고 있기 때문입니다. 이 모니터는 자바의 synchronized 키워드와도 연관이 있구요.
      실제로 모니터 자체를 구현할 일은 아마 없겠지만, 모니터가 뭔지를 알고 있어야 자바로 코드 짜다가 모니터를 사용하고 싶을 때, 혹은 모니터를 사용해서 구현된 자바 클래스 코드를 읽을 때, 잘 쓰고 잘 이해하실 수 있어서 설명하게 됐습니다.
      두 번이나 보시고,, 진짜 대단하셔요~!
      갈가마구님의 열정에 저도 좋은 기운 받습니다 👍

    • @user-sf8mp8qo7h
      @user-sf8mp8qo7h Před 2 lety

      @@ez.아직 개념 정리가 제대로 된게 아니라서 저는 이걸 왜 란 질문이 더 큰 당면 과제 입니다. 이유를 알아야 이해가 되더라구요... 그냥 왜우거나 목적을 모르고 이해를 한건 제것이 되질 않아서, 늦은 시간 답글 감사드립니다.

    • @ez.
      @ez.  Před 2 lety +1

      오 완전 공감합니다
      왜라는 질문이 정말 정말 많이 성장시키더라구요~!
      갈가마구님 나중에 정말 훌륭한 개발자로 성장하실거 같아요
      그때도 쉬운코드 기억해 주실거죠? ㅎㅎ

  • @hml139
    @hml139 Před 2 lety +1

    섭하지~

    • @ez.
      @ez.  Před 2 lety +1

      그래서 섭섭하지 않게 잘 챙겨드렸쥬 ㅎㅎ