🔸재차 강조하기 위한 목적으로 댓글을 남깁니다 스핀락은 계속에서 CPU를 점유하는 형태로 동작하는 락이기 때문에 위험성이 있고(07:08) 그래서 보통의 경우에는 스핀락이 아니라 뮤텍스 락을 사용합니다 왜냐하면 CPU를 계속 점유한다는 것은 리소스 낭비를 의미하고 전체 애플리케이션 퍼포먼스에도 안좋은 영향을 줄 수도 있기 때문이죠 물론 스핀락도 쓰이는 경우가 있습니다 당장 뮤텍스 자체가 스핀락을 써서 구현되고요, 스핀락이 뮤텍스 보다 장점을 보이는 몇몇 케이스가 존재합니다 이 케이스들을 영상에서 간략히 설명했었지만(11:12), deep하게 들어가면 전반적인 상황을 잘 살펴보고 분석 한 후에 스핀락을 쓰는게 더 낫겠다는 확신이 들면 써야 하기 때문에, 보통은 서비스의 안정성을 위해 뮤텍스 락을 쓰는 것을 추천합니다 그리고 사용하시는 프로그래밍 언어마다 제공하는 락의 종류나 형태가 다 다를 수 있기 때문에 정확한 동작 방식은 각 언어의 문서를 참고해 주세요 :)
우와우!! 같은 개발자 크리스찬이시군요!! 반갑습니다~!! 저도 쓰삐용쓰삐용님 항상 응원할게요 :) 자주자주 뵈어요~!! 그리고 critical section과 관련해서는, 맞습니다~! 충분히 그렇게 정의할 수도 있을 것 같아요~ 제 개인적인 생각은, critical section을 'shared data에 접근하는 코드'라고 정의한다면 '공유 데이터 접근'이라는 조금 더 넓은 개념으로 critical section을 정의하게 되는 것 같구요, critical section을 '일관성을 보장하기 위해 한번에 하나의(혹은 제한된 개수의) 스레드나 프로세스만 접근 가능하도록 하는 영역'이라고 정의한다면 '공유 데이터의 일관성 보장 장치'라는 조금 더 좁은 개념으로 critical section을 정의하게 되는 것 같아요 그래서 전자의 정의라면 read only shared data 접근 코드도 critical section이 될 것 같구요, 후자의 정의라면 read only shared data 접근 코드는 critical section이 되지 않을 것 같아요. read only라서 어차피 일관성이 유지될 거니까 일관성을 보장할 장치 자체가 필요 없기 때문이죠~ 좋은 인사이트 주셔서 감사합니다~~ 오늘도 화이팅이에요~!
안녕하세요! 정말 명강의였습니다. 한 가지 궁금한 점이 있는데요. 락을 건자와 락을 푸는 자가 다를 수 있는 특성이 있기 때문에 세마포어로 보는 건지 궁금합니다. 세마포어에서 서로다른 스레드가 wait와 signal을 호출하는 것처럼 뮤텍스에서 lock과 unlock으로 그런식으로 구현하게 된다면, 그건 이미 뮤텍스가 아닌거겠죠?
명강의 감사드립니다!! 덕분에 이해하기가 수월했습니다!!! 영상을 보면서 궁금한 점이 생겼는데요! 세마포어는 여러 스레드/프로세스가 공유자원에 접근할 수 있게 하면서 어떻게 상호 배제를 지키는걸까요? 다른 블로그들도 찾아보고 있는데 명쾌한 답을 얻지 못하여 질문 드립니다 ㅠㅠ 늘 좋은 강의에 감사드립니다 :)
헤헤 영상 유익하게 봐주셔서 감사합니다 :) 세마포어 같은 경우에는 공유 자원이 단 하나가 아니라 여러 경우일 때도 쓸 수 있어서, 가령 화장실에 응가 칸이 세 칸이면 세 칸까지는 동시에 쓸 수 있으니까 이때는 세마포를 통해 동시에 세 개의 프로세스(혹은 스레드)까지 허용할 수 있겠죠 내부적으로 세마포를 어떻게 쓰는지에 대한 구현까지는 딱 이렇게 한다고 정해진 법칙(?)은 저도 잘 못 본 것 같아요 세마포를 쓰는 주체들이 알아서 잘 챙겨줘야 하기 때문에 그런게 아닐까 싶습니다~
안녕하세요 쉬운코드님~ 요즘 다시 운영체제 복습을 하느라 예전에 들었던 강의를 정주행하고 있는데, 처음 강의를 들었을때랑 다른 질문거리가 생기는 거보면, 역시 공부는 끝이 없는거 같네요. 다시 영상을 시청하고 제가 이해한 바는, 스핀락, 뮤텍스, 세마포를 사용하는 목적은 공유되는 자원을 접근함에 있어서 동기화 이슈가 발생하기 때문이고, 즉, 하나의 주체만 공유자원에 접근할 수 있음을 보장하기 위해서 락이라는 수단을 개념적으로 사용하는 것이고, 락을 실제 구현한 매커니즘이 스핀락, 뮤텍스, 세마포라고 이해했습니다. 그런데, 이번에 생긴 의문점은 2가지 입니다. 1. 같은 프로세스에 속한 서로 다른 스레드들 간의 공유 자원 접근은 어떤 상황인지 잘 이해가 됩니다. 한 프로그램 코드를 멀티 스레딩으로 코드를 작성한다면, 코드 상의 여러 스레드가 동시에 접근하는 변수 또는 객체가 있다면, 동기화 매커니즘을 보장하지 않을 경우, 예상하지 못한 결과값을 얻을 테니까요. 이 경우에는 프로그램 코드안에 명백하게 스레드에 의해서 공유되는 변수 또는 객체가 있기 때문에 이해가 잘 되는데요. 반면에, 서로 다른 프로세스에서 공통적으로 접근하는 공유 자원에는 어떤 것들이 있는지 예시를 잘 떠올리는게 어렵습니다. 서로 다른 프로세스라면, 보통 서로 다른 프로그램 코드를 갖게 될 것이고, 그 경우에는 서로 다른 프로그램코드 상에서 동일한 객체 또는 변수를 공유하는 상황이 많이 없을 것 같은데, 서로 다른 프로세스에서 공유 자원을 사용하기 위해 락 메커니즘(스핀락 or 뮤텍스 or 세마포)을 사용하는 상황을 예시로 들어주실 수 있을까요? 2. 뮤텍스와 세마포의 차이점 중, 뮤텍스는 공유 자원을 한 주체만이 사용할 수 있게 제한하고, 반면에 세마포는 value의 값을 조절하여 여러 주체가 동시에 사용하는 것을 허용할 수 있는 것은 이해를 했습니다. 그런데, 뮤텍스와 이진 세마포의 차이점을 설명하시는 부분의 내용이 이해가 잘 안갑니다. 강의 18:16 의 "뮤텍스는 락을 가진자 만이 락을 해제할 수 있지만, 세마포는 그렇지 않다."에 대해 15:26 의 예제는 적절한가에 대한 의문점이 생겼었는데, 강의의 7:45 의 뮤텍스 코드를 보면, 결국 critical section에 들어가기 위해서는 한 프로세스 혹은 스레드가 mutex->lock()을 호출하고, 작업을 모두 끝낸 뒤에는 mutex->unlock()을 호출해야합니다. 강의의 13:23 의 세마포 코드를 봐도, critical section에 들어가기 위해서는 한 프로세스 혹은 스레드가 semaphore->wait()을 호출하고, 작업을 모두 끝낸 뒤에는 semaphore->signal()을 호출해야합니다. 즉, 이진 세마포는 동작방식 자체는 뮤텍스와 동일한 것이라고 생각되는데, 15:26 의 예제의 경우는 프로세스간의 순서를 설정해주기 위해서 세마포의 value의 값이 0으로 설정되어 있는 특수한 케이스이기 때문에, 굳이 한 프로세스 내에서 wait()->signal() 의 순서를 지켜 호출을 할 필요가 없습니다. 그런데, 강의의 18:16 의 "뮤텍스는 락을 가진자 만이 락을 해제할 수 있지만, 세마포는 그렇지 않다." 를 설명하시면서 15:26 의 예시를 드는 것은 살짝 싱크가 맞지 않는다는 느낌이 들었습니다.(혹시 wait() -> signal()의 순서를 지켜 호출을 할 필요가 없다는 것을 뮤텍스와 세마포의 차이점으로 설명하시려던 것인가요?) 뮤텍스가 락을 가진자 만이 락을 해제할 수 있는 것 처럼, 이진 세마포에서 wait()를 호출해서 critical section에 접근하고 있는 주체가 signal()을 호출해야만 다른 스레드들이 이후에 critical section에 접근 할 수 있게 되는 것 아닌가요? 이런 측면에서, 뮤텍스가 priority inheritance 속성을 이용하여 서로 다른 우선순위를 가진 프로세스 혹은 스레드들이 하나의 공유자원에 접근했을 때 생기는 문제를 해결하는 방법에서 어떤 프로세스 혹은 스레드가 lock을 쥐고 있어서 unlock을 해야할지 알 수 있는 거라면, 이진 세마포에서도 wait() 함수를 호출한 프로세스 혹은 스레드가 signal()을 호출할 것이라는 것을 예상할 수 있지 않나요? 두개 사이의 어떤 차이점이 있는지 더 자세한 설명이 필요한 것 같습니다 ㅠㅠ.. + 뮤텍스가 락을 가진 어떤 프로세스나 스레드의 소속이 된다고 하셨는데 그 상황이 되면, 다른 프로세스나 스레드는 unlock() 함수를 호출조차 할 수 없는 것인가요? 뮤텍스가 한 프로세스나 스레드의 소속이 되는 상황을 코드로 보고 싶습니다..
안녕하세요 세승님~ 다시 정주행 중이시다니 정말 대단하십니다~!! 👍 마침 제가 유튜브 채널 관리를 하고 있던 중이었어서 바로 답변을 드릴게요 (보통은 댓글들이 어느 정도 쌓이면 답변을 드립니다 ㅎㅎ) 1. 프로세스의 경우 shared memory 기법이 있어서 서로 다른 프로세스가 공유할 메모리를 지정해서 그 메모리를 같이 사용할 수 있습니다~ 이런 경우라면 같은 이슈가 발생할 수 있겠죠 2. 이 부분은 개인적으로는 조금 더 유연하게 생각을 해주시면 좋을 것 같아요~ 강의를 할 때 모든 것을 완벽하게 코드에 담을 수가 없고, 모든 경우의 수를 다 담을 수도 없죠ㅠ 모든 케이스를 다 설명하려면 리눅스도 윈도우도 다 설명해야하는지 이런 고민들도 생기고요, (이건 실제로 컨텐츠를 준비해 보시면 어떤 의미인지 바로 이해가 되실 것 같아요 :) 실제로 현재 리눅스 소스코드를 보신다면 영상에서 축약된 것보다 훨씬 더 복잡하고 심지어 영상에 있는 코드 자체를 못 찾을 수도 있습니다 (저도 공부할 때 비슷한 경험을 했고요~) 그래서 개인적으로는 영상을 보실 때 조금 더 유연하게 봐주시면 좋을 것 같아요~ 설명하는 모든 부분을 코드에서 찾으려고 하시는 것보다는 기본적인 동작 방식에 대한 이해를 코드로 해주시고, 그외 부가적인 내용은 텍스트 그대로 이해해주시면 어떨까 싶어요 :)
그리고 한 가지 양해를 구하고 싶은 것은 ㅠㅠ 제가 더 자세히 답변을 드리고 싶어도 그렇게 하기가 어려울 것 같아요ㅠ 기술적인 질문에 대한 답변은 세승님 뿐만 아니라 누구에게나 최대한 성의껏 많은 시간을 써서 답변을 드리고 있는데요, 방금 답변 드린 댓글도 제법 축약해서 썼음에도 약 15분 ~ 20분에 가까운 시간을 써서 답변드린 거라서요 ㅠ 저도 하루 24시간에서 시간을 더 알뜰하게 쓸 필요가 있어서 어느 정도 수준 이상으로는 더 자세히 답변을 드리기가 어렵다는 점을 이해 부탁드립니다 ㅠㅠ 대신에 궁금한 부분이 있을 때 세승님께서 (항상은 아니더라도) 종종 깊게 파보셨으면 좋겠어요~ 스스로 묻고 답을 찾는 과정을 통해 많은 성장을 할 수 있거든요 :) 저도 그렇게 하면서 많이 성장을 했더랬죠 ㅎㅎ 긴 글 읽어주셔서 감사합니다~!! 항상 응원합니다~!! 👍👍👍
안녕하세요~! 댓글로 질문도 해주시고 적극적으로 영상 봐주셔서 우선 감사하다는 말씀을 드리고 싶네요 :) 맞습니다~ 말씀하신 것처럼 짧은 순간 빙빙 도는 현상이 생길 수 있습니다. 다만 뮤텍스에서의 spinning은 짧은 시간 동안만 spinning하는 것이 자명하고, 그 짧은 찰나의 spinning은 뮤텍스 락의 올바른 동작을 보장하기 위한 용도로 사용되기 때문에, 이 자체를 스핀'락'이라고 부르지는 않는 것 같아요. 좀 더 설명드리자면, "뮤텍스 '락'을 취득할 수 없다면 그 스레드는 잠들어서 대기상태로 머물게 한다"는 것이 뮤텍스의 핵심이기 때문에, 뮤텍스의 올바른 동작을 보장하기 위해 상대적으로 매우 짧은 찰나의 spinning을 피할 순 없지만, 그래서 이걸 스핀'락'이라고 부르지는 않는 것 같아요. 누군가 이 부분을 질문하실 수도 있겠다 싶었는데 예리한 분석으로 딱 짚어주셨네요~! 최고십니다!!
추가로 mutex관련해서 한 가지 더 질문이 있는데요..! mutex에서는 guard값을 취득해야지만 value값을 취득하거나, 아니면 현재 스레드를 큐에 넣을 수 있는 것처럼 보이는데요 그럼 guard값을 취득하는건 혹시 언제인가요? lock이나 unlock에서 guard값을 1로 바꾼다던지 별도의 작업이 없어보여서, guard을 얻으려는 test_and_set함수가 어떻게 동작해야 while문을 빠져나올 수 있는지 궁금합니다!
오오 seiri o 님 열심히 파고 들어가시는 모습 최고십니다~! 👍 설명을 드리자면 스핀락에서 보셨던 test_and_set 기억나시나요? atomic 명령어였던 그 test_and_set이 뮤텍스에서도 동일하게 쓰이는 거에요 그래서 test_and_set이 내부적으로 guard를 1로 바꿔주게 됩니다~ guard의 처음 값이 0이니까, 여러 스레드가 동시에 lock()을 호출한다고 해도 가장 먼저 test_and_set을 호출한 스레드만 while문을 빠져나오게 되겠죠
운영체제 공부 중에 뮤텍스와 세마포어 관련해서 공부 중에 있는데 다른 자료들로도 궁금증이 해결이 안돼서 이렇게 여쭤봅니다. 세마포어의 정의가 '하나 이상의 프로세스(혹은 스레드)가 임계 구역에 접근할 수 있도록 ...(중략) ...'이라고 했는데, 이게 이해가 되지 않았습니다. 공유 데이터의 경우 하나 이상의 프로세스(혹은 스레드)가 접근을 할 수 있다면 상호 배제의 조건에 부합하지 않다고 생각했습니다. 이러한 고민 중에 DB Connection Pool과 같은 경우 세마포어의 방식을 사용한다는 자료들을 본거 같은데, 이 때 제가 이해한 바로는 뮤텍스와 세마포어는 아예 다른 공유 자원에 대한 이해가 필요하다는 것을 느꼈습니다. 예를 들어서 공유 데이터에 접근 같은 경우에는 무조건 뮤텍스를 통해서 처리하지만, 디비 커넥션 풀 같이 그 안에 여러 개의 커넥션이 존재하는 경우에는 커넥션의 수만큼의 카운팅을 가진 세마포어는 프로세스를 하나씩 할당할 수 있다는 개념으로 받아들였습니다. 물론 그 안에서는 상호 배제가 일어난다고 이해했습니다. 사실 이런 논의 자체가 없는거 보니 크게 중요한 내용은 아니지만, 정확하게 이해하고 싶어서 여쭤봅니다!
아주 좋은 질문을 해주셨습니다 👍 세마포어의 경우 동시에 여러 스레드들이 크리티컬 섹션에 들어갈 수 있기 때문에 그렇다면 상호 배제가 아닌 것 처럼 느껴지기도 하죠 같은 타입의 공유 자원이 여러 개가 있을 수 있기 때문에 이런 경우에 세마포가 역할을 할 수 있다고 생각합니다 말씀하신 것 처럼 connection pool도 좋은 예제가 될 것 같아요 스레드들이 connection pool에 접근할 때는 그 pool이 가질 수 있는 최대 connection 수 만큼만 접근을 허용해야 하기 때문에 이때 세마포어를 쓸 수 있을 것 같고요, 대신 내부적으로 connection을 공유해서 사용하지 않도록 별도의 처리가 필요하겠죠 참고할 만한 자바 예제 코드를 찾아봤는데요, 아래 코드가 이해하시는데 도움이 될 것 같습니다 geekrai.blogspot.com/2013/04/semaphore-and-its-usage-in-java.html 이 코드는 bounded linked list를 구현하면서 최대로 저장할 수 있는 아이템 수 만큼만 스레드가 접근할 수 있도록 세마포어를 사용하고 있습니다 그리고 이때 synchronizedList를 사용해서 공유되는 list에 대한 동기화 이슈도 해결했고요 -- 그리고 뮤텍스와 세마포어의 사용이 공유 자원이 하나인지 혹은 두개 이상인지에 따라 정해지는 것은 아니고요, 이 경우 외에도 세마포어는 시그널 방식이기 때문에 프로세스들의 (혹은 스레드들의) 실행 순서를 정해주고 싶을 때도 사용할 수 있습니다 (이 부분은 영상에서 따로 설명을 했어서 자세한 설명은 생략할게요) -- 마지막으로 멤버십 가입 정말로 감사드립니다!!! 큰 힘이 됩니다!!! 최고최고 👍
선생님 안녕하십니까. 오늘도 역시나 많이 배우고 있습니다(_ _) (11:00) Mutex 설명하는 코드에서 unlock() 부분에 value = 1을 할당하는 것이 else문에서가 아니라 guard=0과 같은 라인이어야 하지 않나요? (즉 else문은 없어야하지 않나요?) 지금상태의 수도코드는 if(큐에 하나라도 대기하는 것이 있을때 ) {깨우기;} else {value = 1} 인데요, 큐에 대기하는걸 깨워도 value는 여전히 0이어서 lock을 잡을 수 없어보여서요. unlock이라면 조건에 의해서가 아닌 언제나 value를 1으로 바꿔줘야 하지 않나 싶습니다. 영상을 보시는 분들께서도 아는 분이 계시다면 답변 주시면 정말 감사하겠습니다! + 추가로 선생님 강의를 보다보면 질문이 많고 선생님께서도 엄청 열심히 답글을 주시는데, 영상별로 자주 묻는 질문 & 답변을 선생님의 블로그에 작성하고 링크를 달아두는건 어떨까 싶습니다. 질문자들도 묻기 전에 찾아볼 수 있고, 같은 질문이 올라오면 블로그 링크를 댓글로 남기면 되고 나름 블로그 홍보도 될 것 같아서요 !ㅋㅋ 영상마다 댓글들 쭉 읽어보는데 모든 질문을 성심성의껏 답변해주시길래 힘드실 것 같아서 한번 고민해봤습니다ㅎㅎ
좋은 강의 감사드립니다. 강의를 보던 중 궁금한점이 생겨 댓글을 남기게 되었습니다. 공유 데이터의 일관성 보장을 위해 한 번에 하나의 프로세스만이 해당 자원에 접근이 가능하게 하고, 이 자원에 접근 할 수 있게 해주는 코드영역을 임계영역이라고 알고 있습니다. 따라서 한 번에 하나의 프로세스만이 임계영역에 진입이 가능하다고 알고있는데 세마포의 경우에는 임계구역에 여러 프로세스(정해진 개수에 한해)가 진입 할 수 있는건가요? 여러프로세스가 임계구역에 동시에 접근을 해도 무관한경우에 해당 방식을 이용하는건가요? 임계구역에는 하나의 프로세스만이 접근이 가능하다고 알고 있는데 하나 이상의 프로세스가 임계구역에 접근이 가능하다고하니 헷갈려서 질문드립니다.
오 좋은 질문입니다 👍 임계 구역(critical section)의 기본적인 개념은 한번에 하나의 프로세스만 접근 가능하다는 개념이 맞지만, 어떤 경우에는 같은 타입의 공유 자원이 여러개가 있을 수 있습니다 예를 들어 공중 화장실의 경우 좌변기가 총 세 개가 있다면 이 자원은 동시에 세 명 까지는 접근이 가능하도록 해야하는 것과 같은 이치입니다 이런 경우에 세마포어가 역할을 할 수 있고 그래서 세마포어의 경우에는 확장된 개념이라고 보시면 될 것 같아요 저도 맨 처음 공부했을 때는 이 부분이 조금 의아했었는데 지금은 세마포어의 경우는 확장해서 이해하고 있습니다 * 참고로 영상에서 말씀드렸던 것처럼 세마포어는 실행 순서를 지정해주고 싶을 때도 사용할 수 있습니다
한번에 이해가 가능한 천재가 아님에 ㅠㅠ 동기화를 하기위한 여러 기법이 있고 각각의 장단점이 있으니 상황에 맞춰 사용하자 로 일던 정리를 스핀락 : 기다려 , 크리티컬 색션의 동작시간이 컨텍스트 스위칭 보다 짧을경우. 유용 뮤텍스 : 여기서 이러지 말고 큐에가서 쉬어,. 무작정 기다리며 cpu잡아먹는게 아니고 큐에 처박아 놓고 다른일 함 세마포어 : 먼저 왔다고 할 수 있는거 아냐 순서를 기다려
오 거의 맞습니다~! 스핀락은 waiting 상태로 바뀌지 않고 계속 반복적으로 확인하는거라 CPU를 계속 쓰는 락이구요 뮤텍스는 이에 반해 큐에 가서 waiting 상태로 대기를 시킵니다. 그리고 락도 하나의 락으로 의미를 가지며, 그리고 락을 쥐고 들어간 애만 오직 락을 해제 할 수 있죠 세마포는 뮤텍스와는 다른 점은 내부적으로 락의 개수가 하나 이상일 수 있다는 점이고, 락을 쥔 애가 아니더라도 다른 애가 락을 해제시킬 수 있죠 모든 것은 처음이 어렵기 때문에 한번에 이해 안되는 것이 당연해요 :) 지금처럼 꾸준히 해주시는게 오히려 대단한 거라고 생각합니다 👍
세마포어에 대한 질문이 하나 있습니다. 여러 곳을 찾아봐도 임계영역에 여러 스레드의 접근을 허용한다는 것만 나와있고 자세한 설명이 없어서 질문드립니다. 제가 궁금한 점은, 하나의 임계영역에 3개의 스레드가 접근을 한다고 했을떄 1. 3개의 스레드가 동일한 임계 영역에서 병렬적으로 연산하게 되는가? 2. 임계영역을 3개로 분할하여, 각자의 스레드가 별도의 영역에 대해 연산을 진행하게 되는가? 3. 3개중 2개는 Busy-wating과 유사하게 활성화는 되어있지만 작업은 하지 않는 형태로 두고 1개만 작업을 진행하는가? 아무리 찾아봐도 명쾌한 답을 못찾겠어서 여쭤봅니다 ㅠ.ㅠ
안녕하세요, 좋은 강의 영상 감사 합니다. 한가지 스핀락과 뮤텍스에 대해 여쭤볼 것이 있는데요. 스핀락이 결국 CPU의 도움을 받아서 하나의 쓰레드가 과도하게 CPU를 점유하는 걸 방지하기 위해 뮤텍스 개념이 나왔다로 이해했습니다. 그런데 뮤텍스도 실제 구성 요소를 보면 test_and_set 메소드로 CPU atomic 한 프로세스가 진행되는데 결국 스핀락 처럼 CPU 타임을 점유하는 거 아닌가요? 스핀락의 단점이 뮤텍스에서도 나타날 거라고 생각이 드는데 왜 다른 개념이 나왔는지 궁금합니다!
아주 좋은 질문을 해주셨습니다 👍 뮤텍스에서도 test_and_set을 사용하기 때문에 spinning 자체는 존재합니다 하지만 스핀락에 비해서는 매우 짧은 순간만 spinnin을 하면서 CPU를 점유하게 되겠죠 (guard에 의해 보호받는 critical section에서 동작하는 코드는 짧은 시간으로 끝나는 코드니까요) 그래서 뮤텍스의 경우 스핀락에 비해 CPU 낭비가 훨씬 적어서 더 이점이 있다고 보시면 되겠습니다 :)
좋은 영상 정말 감사합니다! 듣다 궁금한게 있어서 질문 남겨봅니다.😊 각 thread들이 critical section에 접근 하는 것에 대한 동시성을 보장하기 위해서 스핀락, 뮤텍스, 세마포 같은 방식이 있는 것으로 이해했는데, 각 스핀락과 뮤텍스, 세마포에서 사용하는 lock(), wait(), signal() ...등과 같은 것들은 시스템콜의 일종인지 궁금합니다. 유저모드와 커널모드에 있어서 이런 동시성을 조절하는 과정은 어디서 일어나는 것인가요?
영상을 유익하게 봐주셔서 감사합니다 :) 매우 흥미로운 질문을 해주셨어요~ 저도 덕분에 좀 더 구글링을 해봤는데요, 리눅스 기준으로 말씀드리면 락 관련 함수들은 리눅스 레벨에서 라이브러리 형태(glibc)로 제공을 하고 있고요, 기본적으로는 시스템 콜이 아닌 유저 레벨에서 처리가 되지만 여러 스레드들이 서로 락을 차지하려고 할 때는 누가 락을 쥘 거고 누가 기다릴 것인지 등등을 조정을 해줘야 하는 상황이 생길 수가 있어서, 그때는 futex라는 시스템콜이 사용이 되는 것 같아요 제가 참고한 링크 몇 가지를 남겨 드립니다~ 스택오버플로우에서 관련 질문 : stackoverflow.com/questions/5095781/how-pthread-mutex-lock-is-implemented stackoverflow.com/questions/7067982/mutex-access-and-system-call glibc의 뮤텍스 락 메소드 (futex를 사용하고 있음을 볼 수 있음) : codebrowser.dev/glibc/glibc/nptl/pthread_mutex_lock.c.html futex 시스템 콜 : man7.org/linux/man-pages/man2/futex.2.html
안녕하세요 열심히 듣고 있는 구독자입니다. 보다 의문점이 있는 부분이 있어 질문 드립니다! 0:38에서 크리티컬 섹션에 하나의 프로세스나 스레드가 접근 가능하다고 하셨고 13:14에서 세마포 설명해 주실 때 하나 이상의 프로세스나 스레드가 크리티컬 섹션에 접근 가능하다고 하셨는데 그럼 크리티컬 섹션의 정의가 무너지는 건가요?
구독자님 반갑습니다~! 영상 열심히 봐주신다니 큰 힘이 되네요 :) 좋은 질문을 해주셨어요~! 👍 질문에 우선 간결하게 답변을 드리자면 세마포의 경우를 예외로 보시면 될 것 같아요. 조금 더 자세히 설명을 드리자면 기본적으로 크리티컬 섹션의 개념은 하나의 프로세스나 스레드만 접근 가능한 영역이긴 합니다. 만약 크리티컬 섹션을 (세마포의 경우까지 고려해서) '하나 이상의 제한된 갯수의 스레드나 프로세스만 실행할 수 있는 영역'이라고 넓게 정의한다면 대부분 보통의 락은 크리티컬 섹션에서 하나의 프로세스나 스레드만 접근 가능하도록 동작하기 때문에, 넓은 개념으로 크리티컬 섹션을 이해한다면 이들 락에 대한 이해가 헷갈릴 가능성이 있죠. 세마포는 좀 특별해서, 제한된 수의 스레드나 프로세스가 동시에 크리티컬 섹션 영역에서 실행될 수 있도록 허용하기 때문에 세마포만 구별해서 크리티컬 섹션의 개념을 조금 더 확장해서 이해하시는게 좋지 않을까 싶어요 그래서 다시 정리하면 기본적으로는 크리티컬 섹션의 개념을 '하나의 프로세스나 스레드만 실행 가능한 영역'이라고 이해하시면 좋을 것 같고, 세마포에서는 예외적으로 크리티컬 섹션의 개념을 조금 더 느슨한 혹은 확장된 개념으로 이해하시면 좋을 것 같습니다 :) 투머치인포일 수도 있는데 영상을 만들 때 저도 비슷한 고민이 들었어요 그래서 대학 때 썼던 텍스트북(공룡책)을 참고하고 구글링도 좀 했었는데 (제 기억이 맞다면) 모두가 '크리티컬 섹션은 하나의 프로세스나 스레드만 실행 가능한 영역'으로 정의를 하고 있더라구요~ 그래서 대세를 따라서 설명하는게 이 영상을 보신 분들이 앞으로 다른 문서들을 보실 때 헷갈리시지 않을 것 같아서 저도 같은 형태로 정의하게 됐습니다 :)
강의 정말 잘 들었습니다! 저희 학교 교수님보다 훨씬 잘가르치세요 ㅎㅎ 그런데 하나 궁금한 점이 있어서 질문 드립니다. 예시 들어주신 바이너리 세마포어와 뮤텍스의 코드를 봤을 때 value값 변경 방식이 +=1, -= 1이냐 = 1, =0 이냐의 차이밖에 없는 것 같은데요 이 작은 차이가 어떻게 뮤텍스의 락은 하나의 프로세스만 독점하게하고 세마포어는 아니게 하는지 이유를 알 수 있을까요? + 스핀락의 경우 lock에 volatile 키워드를 붙였는데, 뮤텍스와 세마포어의 경우 volatile이 안보입니다. 왜 이렇게 되는지 이해가 잘 안가서 이것도 답변해주시면 감사하겠습니다. 🙇🏻♂
와우 극찬 감사합니다!! 😊 질문 답변드리면 세마포어의 경우 Class에서 int value = 1;로 선언하는 부분이 꼭 1이 아니라 2, 3, 4로 줄 수 있습니다 그러면 여러 프로세스들(혹은 스레드들)이 동시에 wait()를 호출했을 때 if 문의 value가 0이 될 때까지는 프로세스들이 wait() 호출을 통과해서 (오른쪽 하단의) critical section으로 들어갈 수 있습니다 비슷한 원리로 signal()도 동작을 하고요 오 volatile이 누락됐다고 보시면 될 것 같아요~ 뮤텍스 세마포에도 value와 guard에 volatile이 있어야 될 것 같습니다 (제가 C/C++이 주력인 개발자가 아니라서 만들 때 놓친 것 같네요 ㅠ 스핀락, 뮤텍스, 세마포의 동작 원리 위주로 봐주세용 ㅎㅎ)
(뮤텍스를 쥐려고 대기하는 스레드가 아니라) 뮤텍스를 쥐고 동작하고 있는 스레드의 우선순위를 올려주는 것이 priority inheritance의 핵심이기 때문에 대기큐와는 별개로 봐주셔야 할 것 같아요~ 도움이 될까 싶어서 참조할 만한 링크 드립니다 www.freertos.org/Real-time-embedded-RTOS-mutexes.html Unlike binary semaphores however - mutexes employ priority inheritance. This means that if a high priority task blocks while attempting to obtain a mutex (token) that is currently held by a lower priority task, then the priority of the task holding the token is temporarily raised to that of the blocking task. This mechanism is designed to ensure the higher priority task is kept in the blocked state for the shortest time possible, and in so doing minimise the 'priority inversion' that has already occurred.
강의를 마저 듣던중에 또 다른 질문이 생겨서 댓글드립니다! 강의 9:23 경에 뮤텍스의 value 또한 여러 쓰레드 or 프로세스가 얻고자하는 공유 자원이기 때문에 value의 값을 바꿔줄때마다 critical section 안에서 안전하게 보호받으면서 값을 바꿔줘야한다 라고 설명을 해주셨었는데, 사실 잘 이해와 공감이 되질 않습니다. 뮤텍스를 이용해서 lock과 unlock 하는 이유는 critical section 안에서 실행되는 코드들은 다른 프로세스와 쓰레드의 간섭을 받지 않는 것을 보장해주기 위해서이기 때문에, value를 값을 변경하여 다른 쓰레드 또는 프로세스가 이미 점유되어있는 뮤텍스를 lock 하려고 하는 경우 대기 큐에 넣게 동작시키고, 뮤텍스를 이미 점유하고 있는 쓰레드 혹은 프로세스가 unlock을 통해 대기 큐에 대기중인 쓰레드나 프로세스를 확인하는 것은 이해가 됩니다. 강의자료에 있는 lock 과 unlock 함수는 각각 critical section 진입전, 진입후 에 모두 실행되어 종료되는 함수입니다. 따라서 value의 값이 직접적으로 critical section 안에서는 조작될 이유가 없어보이는데, 설명해주신 부분에서 value가 critical section 안에서 안전하게 보호받으며 값이 바뀐다는 것이 어떤 경우인지 잘 모르겠습니다. 그렇기 때문에 guard 의 용도도 사실 잘 모르겠습니다 ㅠㅠ.. critical section 안에서 value의 값이 변경되도록 코드를 짤 수 는 있지만, 제 입장에서는 매우 illegal 한 상황이라고 생각이 되네요. 좀 더 자세한 설명을 해주실 수 있으면 부탁드립니다. + 여러 프로세스나 쓰레드가 동시에 lock 과 unlock 함수를 호출하는 경우도 생각을 해봤는데, 혹시 이 경우에 생기는 문제점을 위해 guard가 존재하는 건가요? 1. 서로 다른 프로세스가 모두 lock 을 호출하는 경우 2. 서로 다른 프로세스가 모두 unlock 을 호출하는 경우 3. 서로 다른 프로세스가 lock,unlock 을 무작위로 호출하는 경우 긴 댓글 읽어주셔서 감사합니다!
네 맞습니다 :) 아래와 같이 적어주셨는데요, >>> "+ 여러 프로세스나 쓰레드가 동시에 lock 과 unlock 함수를 호출하는 경우도 생각을 해봤는데, 혹시 이 경우에 생기는 문제점을 위해 guard가 존재하는 건가요?" 정확하게 그렇습니다 락을 쓰는 이유가 여러 프로세스/스레드가 같은 데이터에 동시에 접근할 때 데이터를 안전하게 읽거나 쓰기 위해서는 mutual exclusive하게 접근할 수 있도록 해야하는데 그런 측면에서 보면 critical section을 만들기 위해 사용되는 락 또한 여러 프로세스/스레드가 동시에 접근할 수 있기 때문에 락의 값(value)를 바꿔주는 것도 mutual exclusive하게 처리되야 한다는 것을 생각할 수 있습니다 그렇지 않다면 예제에서 value 값을 의도와 다르게 읽을 수 있고 그럼 뮤텍스 락의 메커니즘이 깨질 수 있기 때문이죠 적어주신 3번이 1, 2번을 포함한다고 볼 수 있어서 결국 3번 케이스를 막기 위함이라고 이해할 수 있을 것 같아요~ 덧붙여서 길게 써주신 것이 그냥 길게 써주신 것이 아니라 어떻게 생각하고 계신지 자세히 알려주신 것이라서 저는 오히려 감사했습니다 잘 이해가 안되는 부분을 자세히 알려주시면, 질문 받는 입장에서는 질문 주신 분이 어떻게 생각하고 계신지 더 잘 싱크할 수 있고 그래서 더 정확히 대답을 드릴 수 있거든요 그래서 써주신 댓글을 읽으면서, 제가 질문을 더 잘 이해할 수 있도록 돕기 위해서 자세히 설명하신다는 마음이 느껴져서 감사했습니다 👍
@@ez. 그리고 한가지 의문점이 결국 lock을 위해서 guard를 사용하게 되면 guard 또한 여러 프로세스 및 쓰레드가 동시에 접근할 수 있는 상황이 생겨버리는데, 결국 guard를 mutual exclusive하게 접근할 수 있게 보장하는건 test_and_set 같은 atomic한 함수인거 같네요. 이런 atomic한 함수는 cpu 하드웨어 레벨에서 exclusive 함을 보장하기 때문에 가능한 것이구요. 그럼 차라리 guard를 없애고 value를 수정하는 용도로 test_and_set 과 같은 atomic함을 보장하는 함수를 사용하면 되지 않나요? 이 부분은 파면 팔수록 의문이 계속 생기네요 ㅠㅠ…
@@user-sn2qk9jw6n 충분히 그러실 수 있습니다 :) 아래와 같이 말씀해 주셨는데요, >>> 그럼 차라리 guard를 없애고 value를 수정하는 용도로 test_and_set 과 같은 atomic함을 보장하는 함수를 사용하면 되지 않나요? 맞습니다, 그렇게 동작하는 락이 앞서 설명드린 스핀락(spinlock) 이에요 다만 스핀락은 그 락을 획득할 때 까지 CPU를 계속 소비하는 방식이기 때문에 이 부분을 보완하기 위해 등장한 것이 mutex라고 보시면 되겠습니다~
@@ez. 영상을 다시 돌려보다가 어떤 것 때문에 헷갈렸었는지를 알게되서 마지막으로 댓글 남겨드립니다~ 스핀락과 뮤텍스의 가장 큰 차이점은 '이미 락이 점유되어 있을 시에, 대기 큐에 락을 얻고자하는 프로세스 또는 쓰레드를 넣어서 대기시키고(sleep), 락이 반환되는 경우, 대기 큐에서 기다리던 프로세스 또는 쓰레드를 꺼내 순차적으로 critical section 에 접근할 수 있게 한다.' 라고 이해 했습니다. 구현 상의 lock을 얻는 행위를 또 다른 변수(value)를 이용해서 하기 때문에, value에도 race condition이 발생할 수 있습니다. 그래서, 를 이용하여 value에도 하나의 프로세스 혹은 쓰레드만이 접근하는 할 수 있음을 보장하는 것으로 보이는데요. 헷갈렸던 부분은 영상의 9:23 경의 "뮤텍스의 value 또한 여러 쓰레드 or 프로세스가 얻고자하는 공유 자원이기 때문에 value의 값을 바꿔줄때마다 안전하게 보호받으면서 값을 바꿔줘야한다" 중 보호받아야한다는 부분이었습니다. value 값에 대한 접근은 영상의 코드 상에서는 lock과 unlock 에만 존재합니다. 만약 value 의 값이 critical section 내부의 코드에서 조작된다면, 그건 잘못된 코드 작성이라고 생각됩니다. mutual exclusive 하게 접근 할 수 있는 critical section을 만들기 위해서 사용되는 value를 정작 critical section 안에서 수정할 수 있게 한다면, value가 사용되는 이유가 없겠죠...? 그렇기 때문에, guard 를 통해서 value에 대한 접근을 mutual exclusive 하게 보장하려는 것은 에서라고 보는게 맞지 않나 생각되네요. 예를 들어, 아무도 lock을 점유하고 있지 않은 상황에서, 동시에 쓰레드1, 쓰레드2가 lock 함수를 호출할 경우, while문과 guard을 통한 제어 매커니즘이 없다면, 우연의 일치로 동시에 else 문에 도달할 수 있을 것이고, 그럼 두 쓰레드 모두 value를 0으로 set 하여 락을 얻는 illegal한 상황이 벌어집니다. 하지만, 제어 매커니즘이 있다면, 두 쓰레드 중 먼저 while 내부에 guard를 이용한 atomic한 함수를 호출하는 쓰레드가 cpu 레벨의 도움을 받아 다른 쓰레드의 간섭을 받지않고 guard 값을 바꾸게 될테고, 그렇게 된다면 먼저 호출한 쓰레드는 mutual exclusive하게 나머지 lock 함수의 나머지 코드를 수행할 수 있을 것 같네요. 드디어 뭔가 깨달은 기분이라서 기분이 좋습니다. 코멘트 부탁드리고 항상 감사합니다! + 추가로, mutex의 경우에, lock을 걸은 thread 만이 unlock을 할 수 있지 않나요? 그렇게 된다면, lock이 1개일 경우에는 서로 다른 여러 프로세스 혹은 쓰레드에 의해 동시에 lock 과 unlock 이 동시에 호출되는 상황은 없을 것 같아서요!
안녕하세요! 영상 잘 보았습니다! 추석은 잘 보내셨나요?? 영상 시청 중 궁금한 점이 생겨 댓글 남깁니다...! 1) 해당 락 매카니즘들은 개발자가 동기화가 필요하다고 생각되는 임계 영역에 패키지로 제공되는 세마포어나 뮤텍스등을 사용해야 적용이 되는 부분들 인 건가요??.. 혹시 자바에서 synchronized 키워드를 사용하게 되면 OS 단에서 해당 영역을 임계영역으로 자동 인식하여 위의 락 매카니즘들을 실행 해주기도 할까요,,,?? 당연히 OS 단에서 사용하는 메카니즘과 코드 예시라고 생각하였는데, 예시를 찾아 보다가 C언어에서 동기화 패키지를 제공해 주는 것과 자바에도 concurrent 패키지에 세마포어가 있는 것을 보고 혼란이 오기 시작했습니다 ㅠㅠ... 자바 어플리케이션 소스 단에서 세마포어를 사용할 일이 어떤게 있을까요?... 2) spinlock과 mutex 비교 글을 찾아 보다가 싱글 코어에서는 spinlock을 사용하는 것이 무의미 하다는 글을 보았습니다. 혹시 무의미 하다는 것에 추가적인 설명이 가능하실까요?ㅠㅠ.. 뮤텍스에 비해 성능적으로 장점이 될 수 없어 무의미 하다는 의미로 받아들이면 될까요?? 3) 실제 세마포어나 뮤텍스를 적용하여 개발한 코드 예시나 상황이 혹시 있을까요??? 아니면 혹은 개발 언어가 test_and_set을 지원하거나 동기화 패키지로 지원만 한다면 위 매카니즘을 os, applicaton, web이나 was 서버 등등 여러 부분들에서 동기화 처리를 위해 사용할 수 있는 걸까요??? 위 메카니즘을 실제로 어디서 사용하는지 감이 잘 잡히지가 않습니다 ㅠ 항상 강의 잘 보고 있습니다!! 앞으로도 좋은 강의 많이 부탁드려요! 감사합니다 :)
안녕하세요~ 추석 연휴 별 탈 없이 덕분에 잘 보냈습니다 :) weyoung 님도 추석 연휴 잘 보내셨죠? 아무래도 락 관련 공부하다 보면 많이 헷갈리실 수 있습니다ㅠㅠ 그래도 포기하지 마시고 계속 파고 들어가다 보면 어느 순간 머리속에 정리가 될 거에요~!! 1) 락을 어떻게 사용할지는 사용하시는 언어에서 어떤 형태로 제공하는지에 따라 다릅니다 프로그래밍 언어가 조금 더 락을 사용하기 편리하게 만들어서 개발자게에 클래스/패키지/함수 형태로 제공할 수도 있죠 그 내부가 어떻게 구현되어 있을지는 언어 자체의 구현을 열어봐야 알 수 있습니다 대부분은 OS 레벨에서 제공하는 API를 직간접적으로 사용해서 구현했을 것 같아요 2) 그 글이 어떤 글인지 제가 모르기 때문에 글의 저자가 어떤 의도로 무의미하다고 쓴 것인지 제가 함부로 설명하기는 어려울 것 같습니다 ㅠㅠ 영상의 ua-cam.com/video/gTkvX2Awj6g/v-deo.html 이 부분에서 설명하는 내용이 보신 글과 관련있을 수도 있는데요, 이 부분 내용을 확인해 주시면 도움이 될지도 모르겠어요 3) 동기화 문제가 발생하지 않도록 락을 주로 사용합니다 예를 들어 ua-cam.com/video/vp0Gckz3z64/v-deo.html 이 영상에서 동기화를 하지 않으면 어떤 예상치 못한 현상이 발생할 수 있는지를 설명하고 있는데요, 이 영상의 예제는 뭔가를 카운트를 할 때를 예로 들었어요 두 개 이상의 스레드가 현재까지 카운트한 정보를 공유하는 데이터에 계속해서 업데이트하고 있다면, 락을 사용해서 동기화 문제가 발생하지 않도록 만들 수 있어요 아마 구글링을 해보면 더 많은 예제들이 있을 것 같습니다 * 참고 자바의 synchronized 키워드는 모니터 락을 사용합니다 모니터락은 (이번 영상에서 다룬) 뮤텍스를 사용해서 조금 더 편리한 기능을 제공하도록 정의된 락입니다 이와 관련된 내용은 ua-cam.com/video/Dms1oBmRAlo/v-deo.html를 참고해주시면 되셔요~ 너무 자세히 설명하기에는 조금 어려움이 있어서 이 정도로 답변 드리게 됐습니다 ㅠ 힘내십쇼!! 락은 곧 정복하실 거에요!!!
오늘도 영상 잘 봤습니다~ 뮤텍스 실구현 예제를 찾아보다가 궁금증이 생겨서 질문 드립니다. 한 프로세스 내에서 여러 쓰레드로 공유 데이터를 접근하려하는 경우, 각 쓰레드들은 각자의 스택영역을 가지고, 나머지 코드, 데이터, 힙 영역은 공유하는 것으로 알고 있습니다. 구글링을 하다보니 코드상에서 전역변수(전역변수는 데이터 영역에 위치함)를 이용해서 뮤텍스를 구현해놓은 예제는 많이 봤는데, 힙 영역에 저장되는 데이터를 이용해서 구현해놓은 예제가 없더라구요. 그래서 전역변수를 이용해서 구현한 코드를 살짝 바꿔서 단순히 전역변수 대신 main 함수 내에 포인터와 malloc으로 메모리를 동적할당해서 코드를 돌아가게 해보려고 하니까, (macOS 기준) 실행되다가 segmentation fault가 발생하고 중지됩니다. 혹시 위의 상황에 관련하여 레퍼런스할 만한 자료가 있을까요? 감사합니다.
항상 영상을 애청해 주셔서 너무 감사합니다 :) 질문주신 레퍼런스 상황은 저도 알고 있는 것이 없어요 ㅠ 저도 찾아봐야할 것 같은데요, 하나 궁긍한 것이 실제로 mutex 자체를 c++로 구현하시는 건가요? 아니면 OS 레벨에서 제공하는 mutex를 사용해 보는 것을 구현해 보시는 건가요?
안녕하세요! 일단 너무 훌륭한 동영상 감사합니다 ㅎㅎ 영상을 보던 중 spinlock에서 TestAndSet명령어 관련해서 한가지 질문이 있습니다. T1이 lock=0으로 바꿀 때 T2가 TestAndSet을 실행하던 중이었으면 어떻게 되는지 궁금합니다. 이를 예시로 다시 풀어서 말했을 때, 아래와 같이 순차적으로 실행되게되면 어떻게 되나요? T1이 critical section을 실행하는 중에, T2가 TestAndSet을 호출하면서 T2: int oldLock = *lockPtr; (이 때 oldLock의 값은 1이 됨) T1 : critical section 실행 후 lock = 0으로 수정 T2 : *lockPtr=1 실행함 lock은 다시 1이됨 T2 : return oldLock (이때 oldLock값은 1임 T1이 lock=0으로 수정하기 전에 oldLock에 값을 담았으니까) 이렇게 만약 한줄한줄 서로 병렬적으로 실행되게 되면, lock은 영원히 1로 남을 수도 있지 않을까 해서요 제가 예상하는 답으로는 뒤에 설명하신 atomic명령어 때문에 T2가 TestAndSet명령어를 실행해서 lock에 접근하고 있을 때는 T1이 lock에 값을 덮어씌우지 못하게 막아줄 것 같은데 혹시 제가 예상한 답이 맞을까요?
@@ez. 앗 빠른 답변 감사합니다..ㅠㅠ 제가 말한 부분중에 T1이 lock=0으로 수정하는 부분은 test_and_set에서 진행되는 부분은 아니고 critical section이끝나고 unlock을 위해 lock을 반환할 때인데, 같은 의미로 봐도 되는걸까요? 제가 atomic 명령어에 대해 잘 몰라서 헷갈리는 것 같네요 ㅠㅠ unlock하는 부분도 atomic 명령어라서 test_and_set이랑 겹쳐서 실행 안된다는 의미인거죠?
앗 그렇네요 제가 질문의 의미를 잘못 파악했어요 죄송합니다 ㅠㅠ 답변드리면 test_and_set 처럼 CPU의 지원을 받는 instruction은 해당 test_and_set의 바디 부분이 수행될 동안은 같은 변수에 대해서 다른 프로세스나 스레드가 쓰는 것을 허용하지 않는 것으로 알고 있습니다 그래서 간략하게 설명드리자면, T2가 test_and_set(&lock)을 호출해서 실행중이라면 이 때 T1이 lock = 0을 호출해도 T2의 test_and_set(&lock) 호출이 끝난 후에 T1의 lock = 0이 실행되도록 CPU가 처리합니다
스핀락, 뮤텍스, 세마포어를 포함한 모든 상황에서 스핀락인 test_and_set 함수를 이용해 대기를 하신게 맞을까요? 하나 더 궁금한게 있는데 C 언어에서 구현해보고 있는데 Atomic 키워드를 이용한 변수가 stdatomic.h에 정의되어 있더라구요. stdatomic을 include 하지 않고도 _Atomic 키워드를 쓸 수 있는데 C 언어에서 사용한다면 test_and_set에 선언한 변수와 글로벌 변수를 _Atomic int lock = 0; 이렇게 사용하면 될까요? 아니면 영상에서 설명하신 것과 같이 test_and_set이 아토믹하기 떄문에 그냥 사용하면 되는걸까요?
안녕하세요 :) >> 스핀락, 뮤텍스, 세마포어를 포함한 모든 상황에서 스핀락인 test_and_set 함수를 이용해 대기를 하신게 맞을까요? 우선 test_and_set은 atomic하게 동작하도록 CPU에서 제공하는 명령어(instruction)라고 생각하시면 됩니다~ 그리고 test_and_set을 제공하지 경우에는 다른 atomic operation을 사용해서 구현합니다 그리고 코드 관련 질문은 제가 정확히 답변드리기가 어렵네요 ㅠ 그냥 사용해도 될 것 같긴 한데 정확한 것은 저도 해봐야 알 것 같습니다
안녕하세요 영상 잘 보았습니다. 학습에 큰 도움을 받았어요 감사드립니다. 스핀락은 멀티 프로세서에서만 사용할 수 있다는 내용을 본 적이 잇는데요 아무리 생각해봐도 잘 이해가 안되는데 혹시 설명해주실 수 있나요? ===================== 영상 중간에 싱클 코어에서는 busy waiting 중인 프로세스를 깨울 cpu가 없으니 비효율적이라서 다중 프로세서에서만 사용한다고 이해하면 될까요?
영상 좋게 봐주셔서 감사합니다 :) 조금 더 정확히 워딩을 하자면 '싱글코어에서는 스핀락을 쓰는게 뮤텍스를 쓰는 것에 비해서 전혀 이점이 없고, 멀티 코어에서 그나마 이점이 있을 수 있다'는 의미고요, 왜 그럼 싱글 코어에서는 이점이 없냐면 스핀락을 쥐려고 busy waiting을 하는 프로세스(A)가 스핀락을 쥐려면, 우선 이미 그 스핀락을 쥐고 있는 프로세스(B)가 스핀락을 반환을 해줘야 하는데, 싱글 코어에서는 B가 스핀락을 반환을 하려면 일단 B가 코어에서 실행이 되어야 하기 때문에, 그렇다면 아무리 A가 현재 busy waiting 하고 있어도, 결국은 B로 컨텍스트 스위칭을 해서 B가 스핀락을 반환하고 나중에 다시 A로 컨텍스트 스위칭 되면 그때야 비로서 A가 스핀락을 쥘 수 있습니다 그렇다면 결국 스핀락으로 busy waiting 하는 목적이 최대한 빨리 락을 쥐기 위한 건데 싱글 코어에서는 busy waiting 해봤자 락을 빨리 쥘 수 없으니까 그럴바에야는 뮤텍스를 써서 A는 busy waiting 하지 않고 waiting 상태로 전환하고, A가 busy waiting으로 소비할 뻔했던 CPU 시간은 다른 C나 D 프로세스가 사용할 수 있도록 하는 거죠
안녕하세요. 강의 너무 유용하게 잘 듣고 도움 정말 많이 돼서 감사드립니다. 궁금한게 있는데 뮤텍스에서 가드를 TAS에 안 넣고, 벨류를 바로 TAS에 넣어 사용하면 안되는 건가요? TAS가 공유자원 상호배제하기 위해 사용하는 거고, 벨류를 상호배제하기 위해 가드를 TAS에 넣으면 그냥 벨류를 TAS에 넣어 바로 사용하면 안되나 라는 생각이 들어서요 ㅎㅎ 추가로 뮤텍스나 세마포어에서 슬립에 들어가는 건 OS에서 해주는건지 큐에 넣고 다음에 어떻게 진행되는 건지 궁금합니다.
안녕하세요~! 먼저 영상을 좋게 봐주셔서 감사합니다 :) 질문 주신 내용에서 TAS 관련된 부분은, 만약에 guard를 아예 안쓰고 value만 쓰게 되면 타이밍 이슈 때문에 정상적으로 동작하지 않을 수 있어요 뮤텍스 세마포 관련해서는, 리눅스 기준으로 말씀드리면 얘네들은 pthread 같이 OS의 API 형태(쉽게 말씀드리면 라이브러리)로 제공되는데요, 그 내부 구현을 보시면 락을 얻지 못할 때 어떻게 동작하고 또 나중에 어떻게 깨울지가 구현이 되어 있습니다. 그리고 그렇게 동작하는 와중에 OS의 시스템콜을 사용하는 부분도 있고요~ 자세한 내용은 pthread mutex 구현 코드를 보시면 되는데요, C/C++에 익숙하시고 관심있으시다면 찾아보시는 것도 좋을 것 같아요 :)
답변 드리기에 앞서서 우선 양해를 구하고 싶은 부분이 있습니다ㅠㅠ 제가 여러 사정상 모든 댓글에 자세히 답변을 드리기 어려운 부분이 있습니다ㅠ 그래서 간단하게 설명을 드리거나 혹은 일부 답변을 드리지 못하는 부분이 있어도 이해를 부탁드리겠습니다 🙇♂️ --- 예를 들어서 뮤텍스에서는 큐가 공유 자원이 되기 때문에 큐를 사용하는 코드를 mutual exclusion으로 보호해 주지 않는다면 큐가 이상하게 동작할 수 있습니다 스핀락에서는 큐를 사용하지 않기 때문에 이 문제가 없을 거고요
안녕하세요~ :) 제가 운영체제를 책으로 본 것은 학부 때 (공룡책으로 유명한) Operating System Concepts 라는 책이 전부에요~ 저는 원서로 봤는데 번역서가 있다면 번역 품질이 어떨지 모르겠어요~ 이 책 말고는 따로 사본 책은 없구요, 틈틈히 구글링으로 많이 찾아봤던 것 같아요. 좋은 번역서 책을 추천드리면 좋았을텐데 아쉽네요 ㅠㅠ
영상 도움 받고 갑니다! 영상 보다보니 Mutex 정의가 락을 가질 수 있을 때까지 기다려라는 정의가 틀린것 같습니다. Mutex라는 개념이 Lock Mechanism에 의해서 고안된 개념이고. Shared memory에 접근하게 위해서 System에 요청해서 Mutex를 받아, 주어진 task를 수행하는 것으로, Shared Memory에 접근 할 수 있게 권한을 얻는 것으로 보는 것이 맞는 것 같습니다. Mutex를 받을 수 없을 때, 기다리는 방식이 스핀락이랑 Queue 방식으로 나뉘는것 같구요.
영상 봐주셔서 감사합니다 :) 도움이 됐다니 뿌듯하네요ㅎㅎ 그리고 의견 주신 것도 감사합니다~! 영상에서 설명이 틀린 부분이 있다고 말씀해 주신 것 맞죠? 써주신 글이 제가 정확히 이해하기에 조금 모호하게 느껴지는 부분이 있어서요 ㅠ 그래서 답변을 길게 쓰게 됐는데 (오해없이 쓰려고 몇 번 수정도 했습니다ㅎㅎ) 정성들여 쓰다보니 길어진 거라서 놀라지 마시길요~👍 --- >> Mutex 정의가 락을 가질 수 있을 때까지 기다려라는 정의가 틀린것 같습니다. : 혹시 영상 몇분 몇초 내용이 틀렸다고 생각하신 것인지 알려주시면 제가 더 정확히 답변드릴 수 있을 것 같습니다 ㅠ 지금 당장은, 그 당시에 'mutex는 락을 가질 수 있을 때까지 sleep 상태로 기다리는 것이 특징이다'로 설명했던 것 같습니다 >> Mutex라는 개념이 Lock Mechanism에 의해서 고안된 개념이고. Shared memory에 접근하게 위해서 System에 요청해서 Mutex를 받아, 주어진 task를 수행하는 것으로, Shared Memory에 접근 할 수 있게 권한을 얻는 것으로 보는 것이 맞는 것 같습니다. : 뮤텍스를 권한으로 봐야한다는 주장이신거죠? 저는 '뮤텍스는 락을 얻는 혹은 락이 동작하는 메카니즘 중에 한 종류'로 보고 있고, 이걸 조금 더 추상화해서 설명하면 '뮤텍스는 락의 한 종류'로 볼 수도 있다고 생각합니다 참고로 저는 critical section에서 보장되야하는 mutual exclusion을 의미하는 MutEx와 락의 메카니즘으로서의 뮤텍스를 구분해서 보고 있습니다 >> Mutex를 받을 수 없을 때, 기다리는 방식이 스핀락이랑 Queue 방식으로 나뉘는것 같구요. : 저는 개인적으로는 락이 동작하는 방식을 스핀락, 뮤텍스, 세마포, 모니터 이런식 으로 구분하는 것이 더 명확하고 이해하기 좋다고 생각해요 p.s. 댓글 주신 부분은 맞고 틀리고의 문제가 아닌 영역인 것 같은데, 틀린것 같다고 워딩을 해주신 부분은 개인적으로는 조금 아쉬웠어용 ㅠㅜ
🔸재차 강조하기 위한 목적으로 댓글을 남깁니다
스핀락은 계속에서 CPU를 점유하는 형태로 동작하는 락이기 때문에 위험성이 있고(07:08) 그래서 보통의 경우에는 스핀락이 아니라 뮤텍스 락을 사용합니다
왜냐하면 CPU를 계속 점유한다는 것은 리소스 낭비를 의미하고 전체 애플리케이션 퍼포먼스에도 안좋은 영향을 줄 수도 있기 때문이죠
물론 스핀락도 쓰이는 경우가 있습니다
당장 뮤텍스 자체가 스핀락을 써서 구현되고요,
스핀락이 뮤텍스 보다 장점을 보이는 몇몇 케이스가 존재합니다
이 케이스들을 영상에서 간략히 설명했었지만(11:12), deep하게 들어가면 전반적인 상황을 잘 살펴보고 분석 한 후에 스핀락을 쓰는게 더 낫겠다는 확신이 들면 써야 하기 때문에,
보통은 서비스의 안정성을 위해 뮤텍스 락을 쓰는 것을 추천합니다
그리고 사용하시는 프로그래밍 언어마다 제공하는 락의 종류나 형태가 다 다를 수 있기 때문에 정확한 동작 방식은 각 언어의 문서를 참고해 주세요 :)
진짜 감동의 눈물 흘리면서 봤습니다. 지금까지 그냥 뮤텍스는 이진 세마포어다 하고 그냥 살았는데 이렇게 자세하게 다뤄주시는 분은 처음이네요. 감사합니다.
ㅠㅠㅠㅠ 좋게 봐주셔서 정말 감사합니다!!! 늘 알차게 영상 준비하는 쉬운코드입니다 자주 놀러오세요 :)
이런 강의에 조회수가 말이 되나 ? 이거는 10만회는 나와야되는데 항상 쉬운코드님 강의 질에 비해 조회수가 너무 낮아서 아쉽습니다. 진짜. 강의 진짜 좋음여 !!!
조금만 더 노력 하시면 구글신의 알고리즘님이 도와주실거에요 !!! ㅋ
우와 ㅠㅠ 희망과 칭찬과 응원의 3종 세트 너무나도 감사드립니다 !!!
빠이팅해서 반드시 10만 뷰 넘겨 보겠습니다!!ㅎㅎ👍👍👍
와 설명 진짜 잘하시네요 이 영상을 발견하다니 저는 정말 운이 좋네요!!! 앞으로도 좋은 영상 기대 하겠습니다!
크 극찬 감사합니다~~!! 알차고 좋은 내용으로 계속 인사드릴게용 :)
누구세요...? 누군데 이렇게 설명을 잘해주세요...? 진짜 너무너무너무 대단하십니다...
영상 너무 좋네요! 특히 뮤텍스와 바이너리세마포어 차이점 부분하고 priority inheritance 부분 너무 좋았습니다!
감사합니다 !! 영상 만들 때 많은 노력이 들어갔었는데 좋은 피드백 주셔서 저도 기분이 좋고 뿌듯합니다 !!ㅎㅎ
인터넷에 있는 모든 설명 중에 젤 잘 정리되고 핵심을 잘 짚어주시네요 ^^
우아 ㅠㅠ 엄청난 칭찬 감사합니다ㅠㅠ 👍 앞으로도 핵심전문가가 돼보겠습니다!! ㅎㅎ :)
좋은 강의 영상 공유주셔서 감사합니다.
진짜 너무 좋네요 제가 잘못알고 있던 부분, 궁금했던 부분 모두 해결 되었어요
와우!! 영상이 더할 나위 없이 도움된 것 같아서 저도 정말 정말 뿌듯합니다~! 😄
댓글 감사해요~ :)
대박이네요..
크으... 뮤텍스 세마포어 늘 헷갈렸는데 감사합니다!
와우!! 꾸준히 달리시는 케이구 TV님 멋지십니다!! 저도 귀한 댓글 감사합니다 :)
와 이집 진짜 설명 잘하네
항상 큰 도움이 되고 있습니다. 감사합니다.
댓글 감사합니다!! 항상 화이팅이십니다~!! :)
감사합니다.. 대학 강의만 듣고는 이해하기 어려웠는데 정말 설명 잘 해주시네요.. 저희학교 교수님으로 와주세요...
와우 극찬 너무 감사합니다 :) 채널 이름값 해야죠 😉
강의 퀄리티 너무 미쳤습니다. 감사합니다.
우앗 ㅠㅠ 강의를 좋게 봐주신 것만으로도 감사한데 슈퍼 땡스까지 !!ㅠㅠ 정말 감사합니다!!!
앞으로도 꾸준히 양질의 영상 올릴게요 자주 놀러와 주세요 :)
CS공부 레츠고!
좋은 영상 감사합니다~
레츠고고씽!! 자주 놀러오세용~
설명 정말 잘해주시네요. 감사합니다~~
크 칭찬 감사합니다~! 계속 좋은 영상들로 찾아뵐게요 :)
운영체제 다른 책에서는 critical section을 shared data에 접근하는 코드 라고 부르더군요. 이 또한 영역으로 봐도 문제 없을 것 같습니다. 영역 안에 코드가 있는 것이니까요. 네이버 기술 블로그 봤습니다. 같은 크리스찬으로서 응원합니다.
우와우!! 같은 개발자 크리스찬이시군요!!
반갑습니다~!! 저도 쓰삐용쓰삐용님 항상 응원할게요 :) 자주자주 뵈어요~!!
그리고 critical section과 관련해서는, 맞습니다~! 충분히 그렇게 정의할 수도 있을 것 같아요~
제 개인적인 생각은,
critical section을 'shared data에 접근하는 코드'라고 정의한다면 '공유 데이터 접근'이라는 조금 더 넓은 개념으로 critical section을 정의하게 되는 것 같구요,
critical section을 '일관성을 보장하기 위해 한번에 하나의(혹은 제한된 개수의) 스레드나 프로세스만 접근 가능하도록 하는 영역'이라고 정의한다면 '공유 데이터의 일관성 보장 장치'라는 조금 더 좁은 개념으로 critical section을 정의하게 되는 것 같아요
그래서 전자의 정의라면 read only shared data 접근 코드도 critical section이 될 것 같구요, 후자의 정의라면 read only shared data 접근 코드는 critical section이 되지 않을 것 같아요. read only라서 어차피 일관성이 유지될 거니까 일관성을 보장할 장치 자체가 필요 없기 때문이죠~
좋은 인사이트 주셔서 감사합니다~~
오늘도 화이팅이에요~!
영상 퀄리티와 수준이 너무 대단해요 ❤
헤헿 칭찬의 말씀 감사합니다 😍
정말 대단한 강의력입니다
이해가 정말 잘 돼요 감사합니다
크 다행입니다~!! 👍
안녕하세요! 정말 명강의였습니다.
한 가지 궁금한 점이 있는데요.
락을 건자와 락을 푸는 자가 다를 수 있는 특성이 있기 때문에 세마포어로 보는 건지 궁금합니다. 세마포어에서 서로다른 스레드가 wait와 signal을 호출하는 것처럼 뮤텍스에서 lock과 unlock으로 그런식으로 구현하게 된다면, 그건 이미 뮤텍스가 아닌거겠죠?
좋은 영상 정말 감사드립니다!!
너무 쉽게 설명해주셔서 기술 면접 대비로 블로그에 출처 표기하여 정리해두었습니다 감사합니다!!
와우와우!! 댓글도 감사한데 블로그에 출처까지 표기해 주시다니!!
무한감사 드립니다!! 👍👍👍
너무 잘 봤습니다. 감사합니다.
우아 댓글 너무 감사합니다 :) 더욱 좋은 영상으로 찾아뵐게요~!
너무 잘봤습니다. 쏙쏙 잘 들어오네요!
유익하게 봐주셔서 감사합니다 :) 👍
우와 감사합니다!!!
저도 댓글 감사합니다!!!!
명강의 감사드립니다!! 덕분에 이해하기가 수월했습니다!!!
영상을 보면서 궁금한 점이 생겼는데요!
세마포어는 여러 스레드/프로세스가 공유자원에 접근할 수 있게 하면서 어떻게 상호 배제를 지키는걸까요?
다른 블로그들도 찾아보고 있는데 명쾌한 답을 얻지 못하여 질문 드립니다 ㅠㅠ
늘 좋은 강의에 감사드립니다 :)
헤헤 영상 유익하게 봐주셔서 감사합니다 :)
세마포어 같은 경우에는 공유 자원이 단 하나가 아니라 여러 경우일 때도 쓸 수 있어서,
가령 화장실에 응가 칸이 세 칸이면 세 칸까지는 동시에 쓸 수 있으니까 이때는 세마포를 통해 동시에 세 개의 프로세스(혹은 스레드)까지 허용할 수 있겠죠
내부적으로 세마포를 어떻게 쓰는지에 대한 구현까지는 딱 이렇게 한다고 정해진 법칙(?)은 저도 잘 못 본 것 같아요
세마포를 쓰는 주체들이 알아서 잘 챙겨줘야 하기 때문에 그런게 아닐까 싶습니다~
@@ez. 답변 정말 감사드립니다!!! :) b
안녕하세요 쉬운코드님~
요즘 다시 운영체제 복습을 하느라 예전에 들었던 강의를 정주행하고 있는데,
처음 강의를 들었을때랑 다른 질문거리가 생기는 거보면, 역시 공부는 끝이 없는거 같네요.
다시 영상을 시청하고 제가 이해한 바는,
스핀락, 뮤텍스, 세마포를 사용하는 목적은 공유되는 자원을 접근함에 있어서 동기화 이슈가 발생하기 때문이고,
즉, 하나의 주체만 공유자원에 접근할 수 있음을 보장하기 위해서 락이라는 수단을 개념적으로 사용하는 것이고, 락을 실제 구현한 매커니즘이 스핀락, 뮤텍스, 세마포라고 이해했습니다.
그런데, 이번에 생긴 의문점은 2가지 입니다.
1. 같은 프로세스에 속한 서로 다른 스레드들 간의 공유 자원 접근은 어떤 상황인지 잘 이해가 됩니다.
한 프로그램 코드를 멀티 스레딩으로 코드를 작성한다면, 코드 상의 여러 스레드가 동시에 접근하는 변수 또는 객체가 있다면, 동기화 매커니즘을 보장하지 않을 경우, 예상하지 못한 결과값을 얻을 테니까요.
이 경우에는 프로그램 코드안에 명백하게 스레드에 의해서 공유되는 변수 또는 객체가 있기 때문에 이해가 잘 되는데요.
반면에, 서로 다른 프로세스에서 공통적으로 접근하는 공유 자원에는 어떤 것들이 있는지 예시를 잘 떠올리는게 어렵습니다.
서로 다른 프로세스라면, 보통 서로 다른 프로그램 코드를 갖게 될 것이고, 그 경우에는 서로 다른 프로그램코드 상에서 동일한 객체 또는 변수를 공유하는 상황이 많이 없을 것 같은데,
서로 다른 프로세스에서 공유 자원을 사용하기 위해 락 메커니즘(스핀락 or 뮤텍스 or 세마포)을 사용하는 상황을 예시로 들어주실 수 있을까요?
2. 뮤텍스와 세마포의 차이점 중, 뮤텍스는 공유 자원을 한 주체만이 사용할 수 있게 제한하고, 반면에 세마포는 value의 값을 조절하여 여러 주체가 동시에 사용하는 것을 허용할 수 있는 것은 이해를 했습니다.
그런데, 뮤텍스와 이진 세마포의 차이점을 설명하시는 부분의 내용이 이해가 잘 안갑니다.
강의 18:16 의 "뮤텍스는 락을 가진자 만이 락을 해제할 수 있지만, 세마포는 그렇지 않다."에 대해 15:26 의 예제는 적절한가에 대한 의문점이 생겼었는데,
강의의 7:45 의 뮤텍스 코드를 보면, 결국 critical section에 들어가기 위해서는 한 프로세스 혹은 스레드가 mutex->lock()을 호출하고, 작업을 모두 끝낸 뒤에는 mutex->unlock()을 호출해야합니다.
강의의 13:23 의 세마포 코드를 봐도, critical section에 들어가기 위해서는 한 프로세스 혹은 스레드가 semaphore->wait()을 호출하고, 작업을 모두 끝낸 뒤에는 semaphore->signal()을 호출해야합니다.
즉, 이진 세마포는 동작방식 자체는 뮤텍스와 동일한 것이라고 생각되는데,
15:26 의 예제의 경우는 프로세스간의 순서를 설정해주기 위해서 세마포의 value의 값이 0으로 설정되어 있는 특수한 케이스이기 때문에, 굳이 한 프로세스 내에서 wait()->signal() 의 순서를 지켜 호출을 할 필요가 없습니다.
그런데, 강의의 18:16 의 "뮤텍스는 락을 가진자 만이 락을 해제할 수 있지만, 세마포는 그렇지 않다." 를 설명하시면서 15:26 의 예시를 드는 것은 살짝 싱크가 맞지 않는다는 느낌이 들었습니다.(혹시 wait() -> signal()의 순서를 지켜 호출을 할 필요가 없다는 것을 뮤텍스와 세마포의 차이점으로 설명하시려던 것인가요?)
뮤텍스가 락을 가진자 만이 락을 해제할 수 있는 것 처럼, 이진 세마포에서 wait()를 호출해서 critical section에 접근하고 있는 주체가 signal()을 호출해야만 다른 스레드들이 이후에 critical section에 접근 할 수 있게 되는 것 아닌가요? 이런 측면에서, 뮤텍스가 priority inheritance 속성을 이용하여 서로 다른 우선순위를 가진 프로세스 혹은 스레드들이 하나의 공유자원에 접근했을 때 생기는 문제를 해결하는 방법에서 어떤 프로세스 혹은 스레드가 lock을 쥐고 있어서 unlock을 해야할지 알 수 있는 거라면, 이진 세마포에서도 wait() 함수를 호출한 프로세스 혹은 스레드가 signal()을 호출할 것이라는 것을 예상할 수 있지 않나요? 두개 사이의 어떤 차이점이 있는지 더 자세한 설명이 필요한 것 같습니다 ㅠㅠ..
+ 뮤텍스가 락을 가진 어떤 프로세스나 스레드의 소속이 된다고 하셨는데 그 상황이 되면, 다른 프로세스나 스레드는 unlock() 함수를 호출조차 할 수 없는 것인가요? 뮤텍스가 한 프로세스나 스레드의 소속이 되는 상황을 코드로 보고 싶습니다..
안녕하세요 세승님~ 다시 정주행 중이시다니 정말 대단하십니다~!! 👍 마침 제가 유튜브 채널 관리를 하고 있던 중이었어서 바로 답변을 드릴게요 (보통은 댓글들이 어느 정도 쌓이면 답변을 드립니다 ㅎㅎ)
1. 프로세스의 경우 shared memory 기법이 있어서 서로 다른 프로세스가 공유할 메모리를 지정해서 그 메모리를 같이 사용할 수 있습니다~ 이런 경우라면 같은 이슈가 발생할 수 있겠죠
2. 이 부분은 개인적으로는 조금 더 유연하게 생각을 해주시면 좋을 것 같아요~
강의를 할 때 모든 것을 완벽하게 코드에 담을 수가 없고, 모든 경우의 수를 다 담을 수도 없죠ㅠ
모든 케이스를 다 설명하려면 리눅스도 윈도우도 다 설명해야하는지 이런 고민들도 생기고요,
(이건 실제로 컨텐츠를 준비해 보시면 어떤 의미인지 바로 이해가 되실 것 같아요 :)
실제로 현재 리눅스 소스코드를 보신다면 영상에서 축약된 것보다 훨씬 더 복잡하고 심지어 영상에 있는 코드 자체를 못 찾을 수도 있습니다 (저도 공부할 때 비슷한 경험을 했고요~)
그래서 개인적으로는 영상을 보실 때 조금 더 유연하게 봐주시면 좋을 것 같아요~
설명하는 모든 부분을 코드에서 찾으려고 하시는 것보다는 기본적인 동작 방식에 대한 이해를 코드로 해주시고, 그외 부가적인 내용은 텍스트 그대로 이해해주시면 어떨까 싶어요 :)
그리고 한 가지 양해를 구하고 싶은 것은 ㅠㅠ 제가 더 자세히 답변을 드리고 싶어도 그렇게 하기가 어려울 것 같아요ㅠ
기술적인 질문에 대한 답변은 세승님 뿐만 아니라 누구에게나 최대한 성의껏 많은 시간을 써서 답변을 드리고 있는데요,
방금 답변 드린 댓글도 제법 축약해서 썼음에도 약 15분 ~ 20분에 가까운 시간을 써서 답변드린 거라서요 ㅠ
저도 하루 24시간에서 시간을 더 알뜰하게 쓸 필요가 있어서
어느 정도 수준 이상으로는 더 자세히 답변을 드리기가 어렵다는 점을 이해 부탁드립니다 ㅠㅠ
대신에 궁금한 부분이 있을 때 세승님께서 (항상은 아니더라도) 종종 깊게 파보셨으면 좋겠어요~
스스로 묻고 답을 찾는 과정을 통해 많은 성장을 할 수 있거든요 :)
저도 그렇게 하면서 많이 성장을 했더랬죠 ㅎㅎ
긴 글 읽어주셔서 감사합니다~!!
항상 응원합니다~!! 👍👍👍
뮤텍스 설명하실 때 예제 코드를 보면 동기화를 보장하려고 while문에서 Test and set을 호출하면서 빙빙 돌잖아요? 이러면 결국 스핀락이 생기는거 아닌가요?
안녕하세요~! 댓글로 질문도 해주시고 적극적으로 영상 봐주셔서 우선 감사하다는 말씀을 드리고 싶네요 :)
맞습니다~ 말씀하신 것처럼 짧은 순간 빙빙 도는 현상이 생길 수 있습니다. 다만 뮤텍스에서의 spinning은 짧은 시간 동안만 spinning하는 것이 자명하고, 그 짧은 찰나의 spinning은 뮤텍스 락의 올바른 동작을 보장하기 위한 용도로 사용되기 때문에, 이 자체를 스핀'락'이라고 부르지는 않는 것 같아요.
좀 더 설명드리자면, "뮤텍스 '락'을 취득할 수 없다면 그 스레드는 잠들어서 대기상태로 머물게 한다"는 것이 뮤텍스의 핵심이기 때문에, 뮤텍스의 올바른 동작을 보장하기 위해 상대적으로 매우 짧은 찰나의 spinning을 피할 순 없지만, 그래서 이걸 스핀'락'이라고 부르지는 않는 것 같아요.
누군가 이 부분을 질문하실 수도 있겠다 싶었는데 예리한 분석으로 딱 짚어주셨네요~! 최고십니다!!
@@ez. 여기서 while문은 어떻게 빠져나오게 되는건가요? 짧은시간만 돌다가 탈출하게끔 test_and_set 메소드가 구현이 돼있는걸까요?
@@seirio3505 while문은 guard가 0이 되면 빠져나오구요, guard가 0이 되는 부분은 lock()의 else 끝 부분, unlock()의 끝부분에 있어용
정말감사합니다 제교수시네요
와우 엄청난 극찬인데요?? 감사합니다! 👍
mutex의 unlock함수에서 if문(큐에 대기중인 스레드가 하나라도 있다면)에서 스레드를 깨우는 것뿐 아니라 value를 1로 변경까지 해줘야 하는것 아닌가요? value를 1로 변경하지 않으면 실컷 깨운 스레드가 lock()함수에서 다시 go_to_sleep하게 되니깐요
어후...학교에선 이런거 제대로 안알려준다...
휴..... 힘들다...세마포어 설명 감사합니다.
추가로 mutex관련해서 한 가지 더 질문이 있는데요..!
mutex에서는 guard값을 취득해야지만 value값을 취득하거나, 아니면 현재 스레드를 큐에 넣을 수 있는 것처럼 보이는데요
그럼 guard값을 취득하는건 혹시 언제인가요?
lock이나 unlock에서 guard값을 1로 바꾼다던지 별도의 작업이 없어보여서, guard을 얻으려는 test_and_set함수가 어떻게 동작해야 while문을 빠져나올 수 있는지 궁금합니다!
오오 seiri o 님 열심히 파고 들어가시는 모습 최고십니다~! 👍
설명을 드리자면 스핀락에서 보셨던 test_and_set 기억나시나요? atomic 명령어였던 그 test_and_set이 뮤텍스에서도 동일하게 쓰이는 거에요
그래서 test_and_set이 내부적으로 guard를 1로 바꿔주게 됩니다~
guard의 처음 값이 0이니까, 여러 스레드가 동시에 lock()을 호출한다고 해도 가장 먼저 test_and_set을 호출한 스레드만 while문을 빠져나오게 되겠죠
운영체제 공부 중에 뮤텍스와 세마포어 관련해서 공부 중에 있는데 다른 자료들로도 궁금증이 해결이 안돼서 이렇게 여쭤봅니다.
세마포어의 정의가 '하나 이상의 프로세스(혹은 스레드)가 임계 구역에 접근할 수 있도록 ...(중략) ...'이라고 했는데, 이게 이해가 되지 않았습니다.
공유 데이터의 경우 하나 이상의 프로세스(혹은 스레드)가 접근을 할 수 있다면 상호 배제의 조건에 부합하지 않다고 생각했습니다.
이러한 고민 중에 DB Connection Pool과 같은 경우 세마포어의 방식을 사용한다는 자료들을 본거 같은데, 이 때 제가 이해한 바로는 뮤텍스와 세마포어는 아예 다른 공유 자원에 대한 이해가 필요하다는 것을 느꼈습니다.
예를 들어서 공유 데이터에 접근 같은 경우에는 무조건 뮤텍스를 통해서 처리하지만,
디비 커넥션 풀 같이 그 안에 여러 개의 커넥션이 존재하는 경우에는 커넥션의 수만큼의 카운팅을 가진 세마포어는 프로세스를 하나씩 할당할 수 있다는 개념으로 받아들였습니다.
물론 그 안에서는 상호 배제가 일어난다고 이해했습니다.
사실 이런 논의 자체가 없는거 보니 크게 중요한 내용은 아니지만, 정확하게 이해하고 싶어서 여쭤봅니다!
아주 좋은 질문을 해주셨습니다 👍
세마포어의 경우 동시에 여러 스레드들이 크리티컬 섹션에 들어갈 수 있기 때문에 그렇다면 상호 배제가 아닌 것 처럼 느껴지기도 하죠
같은 타입의 공유 자원이 여러 개가 있을 수 있기 때문에 이런 경우에 세마포가 역할을 할 수 있다고 생각합니다
말씀하신 것 처럼 connection pool도 좋은 예제가 될 것 같아요
스레드들이 connection pool에 접근할 때는 그 pool이 가질 수 있는 최대 connection 수 만큼만 접근을 허용해야 하기 때문에 이때 세마포어를 쓸 수 있을 것 같고요, 대신 내부적으로 connection을 공유해서 사용하지 않도록 별도의 처리가 필요하겠죠
참고할 만한 자바 예제 코드를 찾아봤는데요, 아래 코드가 이해하시는데 도움이 될 것 같습니다
geekrai.blogspot.com/2013/04/semaphore-and-its-usage-in-java.html
이 코드는 bounded linked list를 구현하면서 최대로 저장할 수 있는 아이템 수 만큼만 스레드가 접근할 수 있도록 세마포어를 사용하고 있습니다
그리고 이때 synchronizedList를 사용해서 공유되는 list에 대한 동기화 이슈도 해결했고요
--
그리고 뮤텍스와 세마포어의 사용이 공유 자원이 하나인지 혹은 두개 이상인지에 따라 정해지는 것은 아니고요,
이 경우 외에도 세마포어는 시그널 방식이기 때문에 프로세스들의 (혹은 스레드들의) 실행 순서를 정해주고 싶을 때도 사용할 수 있습니다
(이 부분은 영상에서 따로 설명을 했어서 자세한 설명은 생략할게요)
--
마지막으로 멤버십 가입 정말로 감사드립니다!!!
큰 힘이 됩니다!!!
최고최고 👍
선생님 안녕하십니까.
오늘도 역시나 많이 배우고 있습니다(_ _)
(11:00) Mutex 설명하는 코드에서
unlock() 부분에 value = 1을 할당하는 것이 else문에서가 아니라 guard=0과 같은 라인이어야 하지 않나요? (즉 else문은 없어야하지 않나요?)
지금상태의 수도코드는
if(큐에 하나라도 대기하는 것이 있을때 ) {깨우기;}
else {value = 1}
인데요,
큐에 대기하는걸 깨워도 value는 여전히 0이어서 lock을 잡을 수 없어보여서요.
unlock이라면 조건에 의해서가 아닌 언제나 value를 1으로 바꿔줘야 하지 않나 싶습니다.
영상을 보시는 분들께서도 아는 분이 계시다면 답변 주시면 정말 감사하겠습니다!
+ 추가로 선생님 강의를 보다보면 질문이 많고 선생님께서도 엄청 열심히 답글을 주시는데,
영상별로 자주 묻는 질문 & 답변을 선생님의 블로그에 작성하고 링크를 달아두는건 어떨까 싶습니다.
질문자들도 묻기 전에 찾아볼 수 있고, 같은 질문이 올라오면 블로그 링크를 댓글로 남기면 되고 나름 블로그 홍보도 될 것 같아서요 !ㅋㅋ
영상마다 댓글들 쭉 읽어보는데 모든 질문을 성심성의껏 답변해주시길래 힘드실 것 같아서 한번 고민해봤습니다ㅎㅎ
좋은 강의 감사드립니다. 강의를 보던 중 궁금한점이 생겨 댓글을 남기게 되었습니다. 공유 데이터의 일관성 보장을 위해 한 번에 하나의 프로세스만이 해당 자원에 접근이 가능하게 하고, 이 자원에 접근 할 수 있게 해주는 코드영역을 임계영역이라고 알고 있습니다. 따라서 한 번에 하나의 프로세스만이 임계영역에 진입이 가능하다고 알고있는데 세마포의 경우에는 임계구역에 여러 프로세스(정해진 개수에 한해)가 진입 할 수 있는건가요? 여러프로세스가 임계구역에 동시에 접근을 해도 무관한경우에 해당 방식을 이용하는건가요? 임계구역에는 하나의 프로세스만이 접근이 가능하다고 알고 있는데 하나 이상의 프로세스가 임계구역에 접근이 가능하다고하니 헷갈려서 질문드립니다.
오 좋은 질문입니다 👍
임계 구역(critical section)의 기본적인 개념은 한번에 하나의 프로세스만 접근 가능하다는 개념이 맞지만, 어떤 경우에는 같은 타입의 공유 자원이 여러개가 있을 수 있습니다
예를 들어 공중 화장실의 경우 좌변기가 총 세 개가 있다면 이 자원은 동시에 세 명 까지는 접근이 가능하도록 해야하는 것과 같은 이치입니다
이런 경우에 세마포어가 역할을 할 수 있고 그래서 세마포어의 경우에는 확장된 개념이라고 보시면 될 것 같아요
저도 맨 처음 공부했을 때는 이 부분이 조금 의아했었는데 지금은 세마포어의 경우는 확장해서 이해하고 있습니다
* 참고로 영상에서 말씀드렸던 것처럼 세마포어는 실행 순서를 지정해주고 싶을 때도 사용할 수 있습니다
@@ez. 좋은 영상에 답글 까지 매우 감사드립니다. 영상 보다가 궁금한 점 생기면 댓글 남기겠습니다 : )
여기 1.25배 맛집이네요. 잘먹고 갑니다 ^3^
제 등록금을 나눠드리고 싶네요... 잘 듣고 갑니다!
와우 엄청난 극찬 감사합니다~!!
도움 드릴 수 있어서 뿌듯하네요 :) 댓글 감사합니다 👍
쉬운코드님 몇년동안 보는 지 모루겠습니다. 이런 강의 인프런에 유료로 올리는 건 어떨까요 아깝다,,
한번에 이해가 가능한 천재가 아님에 ㅠㅠ
동기화를 하기위한 여러 기법이 있고 각각의 장단점이 있으니 상황에 맞춰 사용하자 로 일던 정리를
스핀락 : 기다려 , 크리티컬 색션의 동작시간이 컨텍스트 스위칭 보다 짧을경우. 유용
뮤텍스 : 여기서 이러지 말고 큐에가서 쉬어,. 무작정 기다리며 cpu잡아먹는게 아니고 큐에 처박아 놓고 다른일 함
세마포어 : 먼저 왔다고 할 수 있는거 아냐 순서를 기다려
오 거의 맞습니다~!
스핀락은 waiting 상태로 바뀌지 않고 계속 반복적으로 확인하는거라 CPU를 계속 쓰는 락이구요
뮤텍스는 이에 반해 큐에 가서 waiting 상태로 대기를 시킵니다.
그리고 락도 하나의 락으로 의미를 가지며, 그리고 락을 쥐고 들어간 애만 오직 락을 해제 할 수 있죠
세마포는 뮤텍스와는 다른 점은 내부적으로 락의 개수가 하나 이상일 수 있다는 점이고, 락을 쥔 애가 아니더라도 다른 애가 락을 해제시킬 수 있죠
모든 것은 처음이 어렵기 때문에 한번에 이해 안되는 것이 당연해요 :)
지금처럼 꾸준히 해주시는게 오히려 대단한 거라고 생각합니다 👍
세마포어에 대한 질문이 하나 있습니다.
여러 곳을 찾아봐도 임계영역에 여러 스레드의 접근을 허용한다는 것만 나와있고 자세한 설명이 없어서 질문드립니다.
제가 궁금한 점은, 하나의 임계영역에 3개의 스레드가 접근을 한다고 했을떄
1. 3개의 스레드가 동일한 임계 영역에서 병렬적으로 연산하게 되는가?
2. 임계영역을 3개로 분할하여, 각자의 스레드가 별도의 영역에 대해 연산을 진행하게 되는가?
3. 3개중 2개는 Busy-wating과 유사하게 활성화는 되어있지만 작업은 하지 않는 형태로 두고 1개만 작업을 진행하는가?
아무리 찾아봐도 명쾌한 답을 못찾겠어서 여쭤봅니다 ㅠ.ㅠ
안녕하세요, 좋은 강의 영상 감사 합니다. 한가지 스핀락과 뮤텍스에 대해 여쭤볼 것이 있는데요. 스핀락이 결국 CPU의 도움을 받아서 하나의 쓰레드가 과도하게 CPU를 점유하는 걸 방지하기 위해 뮤텍스 개념이 나왔다로 이해했습니다.
그런데 뮤텍스도 실제 구성 요소를 보면 test_and_set 메소드로 CPU atomic 한 프로세스가 진행되는데 결국 스핀락 처럼 CPU 타임을 점유하는 거 아닌가요? 스핀락의 단점이 뮤텍스에서도 나타날 거라고 생각이 드는데 왜 다른 개념이 나왔는지 궁금합니다!
아주 좋은 질문을 해주셨습니다 👍
뮤텍스에서도 test_and_set을 사용하기 때문에 spinning 자체는 존재합니다
하지만 스핀락에 비해서는 매우 짧은 순간만 spinnin을 하면서 CPU를 점유하게 되겠죠 (guard에 의해 보호받는 critical section에서 동작하는 코드는 짧은 시간으로 끝나는 코드니까요)
그래서 뮤텍스의 경우 스핀락에 비해 CPU 낭비가 훨씬 적어서 더 이점이 있다고 보시면 되겠습니다 :)
한 가지만 더 질문하겠습니다!
뮤텍스, 세마포어는 보니까 코드 레벨에서 구현되는 동기화 기법인 것 같은데, 서버가 여러대인 분산 시스템 환경에서는 소용 없는 기법일까요??
좋은 영상 정말 감사합니다!
듣다 궁금한게 있어서 질문 남겨봅니다.😊
각 thread들이 critical section에 접근 하는 것에 대한 동시성을 보장하기 위해서 스핀락, 뮤텍스, 세마포 같은 방식이 있는 것으로 이해했는데,
각 스핀락과 뮤텍스, 세마포에서 사용하는 lock(), wait(), signal() ...등과 같은 것들은 시스템콜의 일종인지 궁금합니다.
유저모드와 커널모드에 있어서 이런 동시성을 조절하는 과정은 어디서 일어나는 것인가요?
영상을 유익하게 봐주셔서 감사합니다 :)
매우 흥미로운 질문을 해주셨어요~ 저도 덕분에 좀 더 구글링을 해봤는데요,
리눅스 기준으로 말씀드리면 락 관련 함수들은 리눅스 레벨에서 라이브러리 형태(glibc)로 제공을 하고 있고요,
기본적으로는 시스템 콜이 아닌 유저 레벨에서 처리가 되지만 여러 스레드들이 서로 락을 차지하려고 할 때는 누가 락을 쥘 거고 누가 기다릴 것인지 등등을 조정을 해줘야 하는 상황이 생길 수가 있어서, 그때는 futex라는 시스템콜이 사용이 되는 것 같아요
제가 참고한 링크 몇 가지를 남겨 드립니다~
스택오버플로우에서 관련 질문 :
stackoverflow.com/questions/5095781/how-pthread-mutex-lock-is-implemented
stackoverflow.com/questions/7067982/mutex-access-and-system-call
glibc의 뮤텍스 락 메소드 (futex를 사용하고 있음을 볼 수 있음) :
codebrowser.dev/glibc/glibc/nptl/pthread_mutex_lock.c.html
futex 시스템 콜 :
man7.org/linux/man-pages/man2/futex.2.html
@@ez. 와.. 정말 감사합니다.. 혹시 구글링을 잘 하는 특별한 방법 같은게 있나요?
음~~ 특별한 방법은 저도 잘 모르겠어요~
(뻔한 얘기지만) 저 같은 경우에는 핵심 키워드들이 꼭 포함되게 검색하긴 해요
예를 들면 이런 식으로요~
'mutex lock use system call'
@@ez. 감사합니다! 이렇게 좋은 강의 만들어주셔서 정말 감사합니다!
저야말로 항상 유익하게 봐주셔서 감사해요 :) 👍
세마포어 방식이 스레드풀과 유사하다고 느끼는데 혹시 세마포어를 설명할 때 스레드풀로 설명해도 괜찮나요??
안녕하세요 열심히 듣고 있는 구독자입니다.
보다 의문점이 있는 부분이 있어 질문 드립니다!
0:38에서 크리티컬 섹션에 하나의 프로세스나 스레드가 접근 가능하다고 하셨고 13:14에서 세마포 설명해 주실 때 하나 이상의 프로세스나 스레드가 크리티컬 섹션에 접근 가능하다고 하셨는데 그럼 크리티컬 섹션의 정의가 무너지는 건가요?
구독자님 반갑습니다~! 영상 열심히 봐주신다니 큰 힘이 되네요 :)
좋은 질문을 해주셨어요~! 👍
질문에 우선 간결하게 답변을 드리자면
세마포의 경우를 예외로 보시면 될 것 같아요.
조금 더 자세히 설명을 드리자면
기본적으로 크리티컬 섹션의 개념은 하나의 프로세스나 스레드만 접근 가능한 영역이긴 합니다.
만약 크리티컬 섹션을 (세마포의 경우까지 고려해서)
'하나 이상의 제한된 갯수의 스레드나 프로세스만 실행할 수 있는 영역'이라고 넓게 정의한다면
대부분 보통의 락은 크리티컬 섹션에서 하나의 프로세스나 스레드만 접근 가능하도록 동작하기 때문에,
넓은 개념으로 크리티컬 섹션을 이해한다면 이들 락에 대한 이해가 헷갈릴 가능성이 있죠.
세마포는 좀 특별해서, 제한된 수의 스레드나 프로세스가 동시에 크리티컬 섹션 영역에서 실행될 수 있도록 허용하기 때문에
세마포만 구별해서 크리티컬 섹션의 개념을 조금 더 확장해서 이해하시는게 좋지 않을까 싶어요
그래서 다시 정리하면
기본적으로는 크리티컬 섹션의 개념을 '하나의 프로세스나 스레드만 실행 가능한 영역'이라고 이해하시면 좋을 것 같고,
세마포에서는 예외적으로 크리티컬 섹션의 개념을 조금 더 느슨한 혹은 확장된 개념으로 이해하시면 좋을 것 같습니다 :)
투머치인포일 수도 있는데
영상을 만들 때 저도 비슷한 고민이 들었어요
그래서 대학 때 썼던 텍스트북(공룡책)을 참고하고 구글링도 좀 했었는데
(제 기억이 맞다면) 모두가 '크리티컬 섹션은 하나의 프로세스나 스레드만 실행 가능한 영역'으로 정의를 하고 있더라구요~
그래서 대세를 따라서 설명하는게 이 영상을 보신 분들이 앞으로 다른 문서들을 보실 때 헷갈리시지 않을 것 같아서
저도 같은 형태로 정의하게 됐습니다 :)
@@ez. 네 잘 이해되었습니다. 감사합니다!!!
다행입니다~ 화이팅하십숑~!
바이너리세마포어와 카운팅 세마포어의 차이입니다
코드부분에서 일시정지하고 20분간 고뇌에 빠져야만 이해할 수 있는 능지...서럽다
세마포어가 prioiryt inheritance속성이 없다면, 강의에서 설명해주신 상황에서는 세마포어는 어떻게 해결하나요?
뮤텍스에 priority inheritance 는 모르고 있었는데 새로 알고가요! 그리고 혹시 뭐 후원같은거는 못여시나요? 영상 제작하실 때 드실 커피값이라도 보내드리고 싶네요...
와 ㅠㅠㅠㅠ 감동이네요, 이런 말씀 해주신 분이 처음입니다 ㅠㅠ
아직 생각해 본 적은 없지만,, 혹시 뭔가 아이디어가 생기면 공유드릴게요
마음 써주셔서 진짜 정말 감사합니다 ㅠㅠ 👍👍👍👍👍
강의 정말 잘 들었습니다! 저희 학교 교수님보다 훨씬 잘가르치세요 ㅎㅎ
그런데 하나 궁금한 점이 있어서 질문 드립니다.
예시 들어주신 바이너리 세마포어와 뮤텍스의 코드를 봤을 때 value값 변경 방식이 +=1, -= 1이냐 = 1, =0 이냐의 차이밖에 없는 것 같은데요
이 작은 차이가 어떻게 뮤텍스의 락은 하나의 프로세스만 독점하게하고 세마포어는 아니게 하는지 이유를 알 수 있을까요?
+
스핀락의 경우 lock에 volatile 키워드를 붙였는데, 뮤텍스와 세마포어의 경우 volatile이 안보입니다. 왜 이렇게 되는지 이해가 잘 안가서 이것도 답변해주시면 감사하겠습니다.
🙇🏻♂
와우 극찬 감사합니다!! 😊
질문 답변드리면 세마포어의 경우 Class에서 int value = 1;로 선언하는 부분이 꼭 1이 아니라 2, 3, 4로 줄 수 있습니다
그러면 여러 프로세스들(혹은 스레드들)이 동시에 wait()를 호출했을 때 if 문의 value가 0이 될 때까지는 프로세스들이 wait() 호출을 통과해서 (오른쪽 하단의) critical section으로 들어갈 수 있습니다
비슷한 원리로 signal()도 동작을 하고요
오 volatile이 누락됐다고 보시면 될 것 같아요~ 뮤텍스 세마포에도 value와 guard에 volatile이 있어야 될 것 같습니다
(제가 C/C++이 주력인 개발자가 아니라서 만들 때 놓친 것 같네요 ㅠ 스핀락, 뮤텍스, 세마포의 동작 원리 위주로 봐주세용 ㅎㅎ)
19:02 질문있는데요 . 뮤텍스에서 보통 대기큐는 우선순위 방식으로 구현하나요? FIFO 방식이라던가 그렇게도 사용할 수 있지도 않나요? 만약 FIFO 방식이라면 priority inheritance는 무용지물 아닌가요?
(뮤텍스를 쥐려고 대기하는 스레드가 아니라) 뮤텍스를 쥐고 동작하고 있는 스레드의 우선순위를 올려주는 것이 priority inheritance의 핵심이기 때문에 대기큐와는 별개로 봐주셔야 할 것 같아요~
도움이 될까 싶어서 참조할 만한 링크 드립니다
www.freertos.org/Real-time-embedded-RTOS-mutexes.html
Unlike binary semaphores however - mutexes employ priority inheritance. This means that if a high priority task blocks while attempting to obtain a mutex (token) that is currently held by a lower priority task, then the priority of the task holding the token is temporarily raised to that of the blocking task. This mechanism is designed to ensure the higher priority task is kept in the blocked state for the shortest time possible, and in so doing minimise the 'priority inversion' that has already occurred.
강의를 마저 듣던중에 또 다른 질문이 생겨서 댓글드립니다!
강의 9:23 경에 뮤텍스의 value 또한 여러 쓰레드 or 프로세스가 얻고자하는 공유 자원이기 때문에 value의 값을 바꿔줄때마다 critical section 안에서 안전하게 보호받으면서 값을 바꿔줘야한다 라고 설명을 해주셨었는데,
사실 잘 이해와 공감이 되질 않습니다.
뮤텍스를 이용해서 lock과 unlock 하는 이유는 critical section 안에서 실행되는 코드들은 다른 프로세스와 쓰레드의 간섭을 받지 않는 것을 보장해주기 위해서이기 때문에, value를 값을 변경하여 다른 쓰레드 또는 프로세스가 이미 점유되어있는 뮤텍스를 lock 하려고 하는 경우 대기 큐에 넣게 동작시키고, 뮤텍스를 이미 점유하고 있는 쓰레드 혹은 프로세스가 unlock을 통해 대기 큐에 대기중인 쓰레드나 프로세스를 확인하는 것은 이해가 됩니다.
강의자료에 있는 lock 과 unlock 함수는 각각 critical section 진입전, 진입후 에 모두 실행되어 종료되는 함수입니다. 따라서 value의 값이 직접적으로 critical section 안에서는 조작될 이유가 없어보이는데, 설명해주신 부분에서 value가 critical section 안에서 안전하게 보호받으며 값이 바뀐다는 것이 어떤 경우인지 잘 모르겠습니다. 그렇기 때문에 guard 의 용도도 사실 잘 모르겠습니다 ㅠㅠ.. critical section 안에서 value의 값이 변경되도록 코드를 짤 수 는 있지만, 제 입장에서는 매우 illegal 한 상황이라고 생각이 되네요. 좀 더 자세한 설명을 해주실 수 있으면 부탁드립니다.
+ 여러 프로세스나 쓰레드가 동시에 lock 과 unlock 함수를 호출하는 경우도 생각을 해봤는데, 혹시 이 경우에 생기는 문제점을 위해 guard가 존재하는 건가요?
1. 서로 다른 프로세스가 모두 lock 을 호출하는 경우
2. 서로 다른 프로세스가 모두 unlock 을 호출하는 경우
3. 서로 다른 프로세스가 lock,unlock 을 무작위로 호출하는 경우
긴 댓글 읽어주셔서 감사합니다!
네 맞습니다 :)
아래와 같이 적어주셨는데요,
>>> "+ 여러 프로세스나 쓰레드가 동시에 lock 과 unlock 함수를 호출하는 경우도 생각을 해봤는데, 혹시 이 경우에 생기는 문제점을 위해 guard가 존재하는 건가요?"
정확하게 그렇습니다
락을 쓰는 이유가
여러 프로세스/스레드가 같은 데이터에 동시에 접근할 때
데이터를 안전하게 읽거나 쓰기 위해서는 mutual exclusive하게 접근할 수 있도록 해야하는데
그런 측면에서 보면 critical section을 만들기 위해 사용되는 락 또한 여러 프로세스/스레드가 동시에 접근할 수 있기 때문에
락의 값(value)를 바꿔주는 것도 mutual exclusive하게 처리되야 한다는 것을 생각할 수 있습니다
그렇지 않다면 예제에서 value 값을 의도와 다르게 읽을 수 있고 그럼 뮤텍스 락의 메커니즘이 깨질 수 있기 때문이죠
적어주신 3번이 1, 2번을 포함한다고 볼 수 있어서 결국 3번 케이스를 막기 위함이라고 이해할 수 있을 것 같아요~
덧붙여서
길게 써주신 것이 그냥 길게 써주신 것이 아니라 어떻게 생각하고 계신지 자세히 알려주신 것이라서 저는 오히려 감사했습니다
잘 이해가 안되는 부분을 자세히 알려주시면, 질문 받는 입장에서는 질문 주신 분이 어떻게 생각하고 계신지 더 잘 싱크할 수 있고 그래서 더 정확히 대답을 드릴 수 있거든요
그래서 써주신 댓글을 읽으면서, 제가 질문을 더 잘 이해할 수 있도록 돕기 위해서 자세히 설명하신다는 마음이 느껴져서 감사했습니다 👍
@@ez. 항상 친절한 답변 감사합니다.
@@ez. 그리고 한가지 의문점이 결국 lock을 위해서 guard를 사용하게 되면 guard 또한 여러 프로세스 및 쓰레드가 동시에 접근할 수 있는 상황이 생겨버리는데, 결국 guard를 mutual exclusive하게 접근할 수 있게 보장하는건 test_and_set 같은 atomic한 함수인거 같네요. 이런 atomic한 함수는 cpu 하드웨어 레벨에서 exclusive 함을 보장하기 때문에 가능한 것이구요. 그럼 차라리 guard를 없애고 value를 수정하는 용도로 test_and_set 과 같은 atomic함을 보장하는 함수를 사용하면 되지 않나요?
이 부분은 파면 팔수록 의문이 계속 생기네요 ㅠㅠ…
@@user-sn2qk9jw6n 충분히 그러실 수 있습니다 :)
아래와 같이 말씀해 주셨는데요,
>>> 그럼 차라리 guard를 없애고 value를 수정하는 용도로 test_and_set 과 같은 atomic함을 보장하는 함수를 사용하면 되지 않나요?
맞습니다, 그렇게 동작하는 락이 앞서 설명드린 스핀락(spinlock) 이에요
다만 스핀락은 그 락을 획득할 때 까지 CPU를 계속 소비하는 방식이기 때문에 이 부분을 보완하기 위해 등장한 것이 mutex라고 보시면 되겠습니다~
@@ez. 영상을 다시 돌려보다가 어떤 것 때문에 헷갈렸었는지를 알게되서 마지막으로 댓글 남겨드립니다~
스핀락과 뮤텍스의 가장 큰 차이점은 '이미 락이 점유되어 있을 시에, 대기 큐에 락을 얻고자하는 프로세스 또는 쓰레드를 넣어서 대기시키고(sleep), 락이 반환되는 경우, 대기 큐에서 기다리던 프로세스 또는 쓰레드를 꺼내 순차적으로 critical section 에 접근할 수 있게 한다.' 라고 이해 했습니다.
구현 상의 lock을 얻는 행위를 또 다른 변수(value)를 이용해서 하기 때문에, value에도 race condition이 발생할 수 있습니다. 그래서, 를 이용하여 value에도 하나의 프로세스 혹은 쓰레드만이 접근하는 할 수 있음을 보장하는 것으로 보이는데요.
헷갈렸던 부분은 영상의 9:23 경의 "뮤텍스의 value 또한 여러 쓰레드 or 프로세스가 얻고자하는 공유 자원이기 때문에 value의 값을 바꿔줄때마다 안전하게 보호받으면서 값을 바꿔줘야한다" 중 보호받아야한다는 부분이었습니다.
value 값에 대한 접근은 영상의 코드 상에서는 lock과 unlock 에만 존재합니다. 만약 value 의 값이 critical section 내부의 코드에서 조작된다면, 그건 잘못된 코드 작성이라고 생각됩니다. mutual exclusive 하게 접근 할 수 있는 critical section을 만들기 위해서 사용되는 value를 정작 critical section 안에서 수정할 수 있게 한다면, value가 사용되는 이유가 없겠죠...?
그렇기 때문에, guard 를 통해서 value에 대한 접근을 mutual exclusive 하게 보장하려는 것은 에서라고 보는게 맞지 않나 생각되네요.
예를 들어, 아무도 lock을 점유하고 있지 않은 상황에서, 동시에 쓰레드1, 쓰레드2가 lock 함수를 호출할 경우, while문과 guard을 통한 제어 매커니즘이 없다면, 우연의 일치로 동시에 else 문에 도달할 수 있을 것이고, 그럼 두 쓰레드 모두 value를 0으로 set 하여 락을 얻는 illegal한 상황이 벌어집니다. 하지만, 제어 매커니즘이 있다면, 두 쓰레드 중 먼저 while 내부에 guard를 이용한 atomic한 함수를 호출하는 쓰레드가 cpu 레벨의 도움을 받아 다른 쓰레드의 간섭을 받지않고 guard 값을 바꾸게 될테고, 그렇게 된다면 먼저 호출한 쓰레드는 mutual exclusive하게 나머지 lock 함수의 나머지 코드를 수행할 수 있을 것 같네요.
드디어 뭔가 깨달은 기분이라서 기분이 좋습니다. 코멘트 부탁드리고 항상 감사합니다!
+ 추가로, mutex의 경우에, lock을 걸은 thread 만이 unlock을 할 수 있지 않나요? 그렇게 된다면, lock이 1개일 경우에는 서로 다른 여러 프로세스 혹은 쓰레드에 의해 동시에 lock 과 unlock 이 동시에 호출되는 상황은 없을 것 같아서요!
안녕하세요! 영상 잘 보았습니다!
추석은 잘 보내셨나요??
영상 시청 중 궁금한 점이 생겨 댓글 남깁니다...!
1)
해당 락 매카니즘들은 개발자가 동기화가 필요하다고 생각되는 임계 영역에 패키지로 제공되는 세마포어나 뮤텍스등을 사용해야 적용이 되는 부분들 인 건가요??..
혹시 자바에서 synchronized 키워드를 사용하게 되면 OS 단에서 해당 영역을 임계영역으로 자동 인식하여 위의 락 매카니즘들을 실행 해주기도 할까요,,,??
당연히 OS 단에서 사용하는 메카니즘과 코드 예시라고 생각하였는데, 예시를 찾아 보다가 C언어에서 동기화 패키지를 제공해 주는 것과 자바에도 concurrent 패키지에 세마포어가 있는 것을 보고 혼란이 오기 시작했습니다 ㅠㅠ...
자바 어플리케이션 소스 단에서 세마포어를 사용할 일이 어떤게 있을까요?...
2) spinlock과 mutex 비교 글을 찾아 보다가 싱글 코어에서는 spinlock을 사용하는 것이 무의미 하다는 글을 보았습니다.
혹시 무의미 하다는 것에 추가적인 설명이 가능하실까요?ㅠㅠ.. 뮤텍스에 비해 성능적으로 장점이 될 수 없어 무의미 하다는 의미로 받아들이면 될까요??
3) 실제 세마포어나 뮤텍스를 적용하여 개발한 코드 예시나 상황이 혹시 있을까요???
아니면 혹은 개발 언어가 test_and_set을 지원하거나 동기화 패키지로 지원만 한다면 위 매카니즘을 os, applicaton, web이나 was 서버 등등 여러 부분들에서 동기화 처리를 위해 사용할 수 있는 걸까요??? 위 메카니즘을 실제로 어디서 사용하는지 감이 잘 잡히지가 않습니다 ㅠ
항상 강의 잘 보고 있습니다!! 앞으로도 좋은 강의 많이 부탁드려요! 감사합니다 :)
안녕하세요~ 추석 연휴 별 탈 없이 덕분에 잘 보냈습니다 :)
weyoung 님도 추석 연휴 잘 보내셨죠?
아무래도 락 관련 공부하다 보면 많이 헷갈리실 수 있습니다ㅠㅠ
그래도 포기하지 마시고 계속 파고 들어가다 보면 어느 순간 머리속에 정리가 될 거에요~!!
1)
락을 어떻게 사용할지는 사용하시는 언어에서 어떤 형태로 제공하는지에 따라 다릅니다
프로그래밍 언어가 조금 더 락을 사용하기 편리하게 만들어서 개발자게에 클래스/패키지/함수 형태로 제공할 수도 있죠
그 내부가 어떻게 구현되어 있을지는 언어 자체의 구현을 열어봐야 알 수 있습니다
대부분은 OS 레벨에서 제공하는 API를 직간접적으로 사용해서 구현했을 것 같아요
2)
그 글이 어떤 글인지 제가 모르기 때문에 글의 저자가 어떤 의도로 무의미하다고 쓴 것인지 제가 함부로 설명하기는 어려울 것 같습니다 ㅠㅠ
영상의 ua-cam.com/video/gTkvX2Awj6g/v-deo.html 이 부분에서 설명하는 내용이 보신 글과 관련있을 수도 있는데요, 이 부분 내용을 확인해 주시면 도움이 될지도 모르겠어요
3)
동기화 문제가 발생하지 않도록 락을 주로 사용합니다
예를 들어 ua-cam.com/video/vp0Gckz3z64/v-deo.html 이 영상에서 동기화를 하지 않으면 어떤 예상치 못한 현상이 발생할 수 있는지를 설명하고 있는데요, 이 영상의 예제는 뭔가를 카운트를 할 때를 예로 들었어요
두 개 이상의 스레드가 현재까지 카운트한 정보를 공유하는 데이터에 계속해서 업데이트하고 있다면, 락을 사용해서 동기화 문제가 발생하지 않도록 만들 수 있어요
아마 구글링을 해보면 더 많은 예제들이 있을 것 같습니다
* 참고
자바의 synchronized 키워드는 모니터 락을 사용합니다
모니터락은 (이번 영상에서 다룬) 뮤텍스를 사용해서 조금 더 편리한 기능을 제공하도록 정의된 락입니다
이와 관련된 내용은 ua-cam.com/video/Dms1oBmRAlo/v-deo.html를 참고해주시면 되셔요~
너무 자세히 설명하기에는 조금 어려움이 있어서 이 정도로 답변 드리게 됐습니다 ㅠ
힘내십쇼!!
락은 곧 정복하실 거에요!!!
@@ez. 서두없이 작성하였는데 친절하게 답변해주셔서 감사합니다! 말씀주신대로 반복해서 생각해 보도록 하겠습니다!ㅎㅎ 항상 답변 감사드립니다!
오늘도 영상 잘 봤습니다~
뮤텍스 실구현 예제를 찾아보다가 궁금증이 생겨서 질문 드립니다.
한 프로세스 내에서 여러 쓰레드로 공유 데이터를 접근하려하는 경우, 각 쓰레드들은 각자의 스택영역을 가지고,
나머지 코드, 데이터, 힙 영역은 공유하는 것으로 알고 있습니다.
구글링을 하다보니 코드상에서 전역변수(전역변수는 데이터 영역에 위치함)를 이용해서 뮤텍스를 구현해놓은 예제는 많이 봤는데, 힙 영역에 저장되는 데이터를 이용해서 구현해놓은 예제가 없더라구요.
그래서 전역변수를 이용해서 구현한 코드를 살짝 바꿔서 단순히 전역변수 대신 main 함수 내에 포인터와 malloc으로 메모리를 동적할당해서 코드를 돌아가게 해보려고 하니까, (macOS 기준) 실행되다가 segmentation fault가 발생하고 중지됩니다.
혹시 위의 상황에 관련하여 레퍼런스할 만한 자료가 있을까요? 감사합니다.
항상 영상을 애청해 주셔서 너무 감사합니다 :)
질문주신 레퍼런스 상황은 저도 알고 있는 것이 없어요 ㅠ 저도 찾아봐야할 것 같은데요,
하나 궁긍한 것이 실제로 mutex 자체를 c++로 구현하시는 건가요?
아니면 OS 레벨에서 제공하는 mutex를 사용해 보는 것을 구현해 보시는 건가요?
@@ez. 후자에 해당합니다~ pthread_mutex_init() 같은 함수를 이용했습니다
@@user-sn2qk9jw6n 오 넵 알겠습니당~ 저도 여유될 때 확인해 보고 혹시 공유드릴만한 부분이 있으면 댓글 다시 남길게요 👍
안녕하세요! 일단 너무 훌륭한 동영상 감사합니다 ㅎㅎ
영상을 보던 중 spinlock에서 TestAndSet명령어 관련해서 한가지 질문이 있습니다.
T1이 lock=0으로 바꿀 때 T2가 TestAndSet을 실행하던 중이었으면 어떻게 되는지 궁금합니다.
이를 예시로 다시 풀어서 말했을 때, 아래와 같이 순차적으로 실행되게되면 어떻게 되나요?
T1이 critical section을 실행하는 중에,
T2가 TestAndSet을 호출하면서
T2: int oldLock = *lockPtr; (이 때 oldLock의 값은 1이 됨)
T1 : critical section 실행 후 lock = 0으로 수정
T2 : *lockPtr=1 실행함 lock은 다시 1이됨
T2 : return oldLock (이때 oldLock값은 1임 T1이 lock=0으로 수정하기 전에 oldLock에 값을 담았으니까)
이렇게 만약 한줄한줄 서로 병렬적으로 실행되게 되면, lock은 영원히 1로 남을 수도 있지 않을까 해서요
제가 예상하는 답으로는 뒤에 설명하신 atomic명령어 때문에 T2가 TestAndSet명령어를 실행해서 lock에 접근하고 있을 때는 T1이 lock에 값을 덮어씌우지 못하게 막아줄 것 같은데 혹시 제가 예상한 답이 맞을까요?
크~!! 천재십니다
예상하신 답이 맞습니다!!👍 TestAndSet은 atomic 명령어이기 때문에 병렬로 처리될 수 없죵
@@ez. 앗 빠른 답변 감사합니다..ㅠㅠ 제가 말한 부분중에 T1이 lock=0으로 수정하는 부분은 test_and_set에서 진행되는 부분은 아니고 critical section이끝나고 unlock을 위해 lock을 반환할 때인데, 같은 의미로 봐도 되는걸까요?
제가 atomic 명령어에 대해 잘 몰라서 헷갈리는 것 같네요 ㅠㅠ unlock하는 부분도 atomic 명령어라서 test_and_set이랑 겹쳐서 실행 안된다는 의미인거죠?
앗 그렇네요 제가 질문의 의미를 잘못 파악했어요 죄송합니다 ㅠㅠ
답변드리면 test_and_set 처럼 CPU의 지원을 받는 instruction은 해당 test_and_set의 바디 부분이 수행될 동안은 같은 변수에 대해서 다른 프로세스나 스레드가 쓰는 것을 허용하지 않는 것으로 알고 있습니다
그래서 간략하게 설명드리자면,
T2가 test_and_set(&lock)을 호출해서 실행중이라면 이 때 T1이 lock = 0을 호출해도 T2의 test_and_set(&lock) 호출이 끝난 후에 T1의 lock = 0이 실행되도록 CPU가 처리합니다
@@ez. 크 깔꼼한 답변 감사합니다!
스핀락, 뮤텍스, 세마포어를 포함한 모든 상황에서 스핀락인 test_and_set 함수를 이용해 대기를 하신게 맞을까요? 하나 더 궁금한게 있는데 C 언어에서 구현해보고 있는데 Atomic 키워드를 이용한 변수가 stdatomic.h에 정의되어 있더라구요. stdatomic을 include 하지 않고도 _Atomic 키워드를 쓸 수 있는데 C 언어에서 사용한다면 test_and_set에 선언한 변수와 글로벌 변수를 _Atomic int lock = 0; 이렇게 사용하면 될까요? 아니면 영상에서 설명하신 것과 같이 test_and_set이 아토믹하기 떄문에 그냥 사용하면 되는걸까요?
안녕하세요 :)
>> 스핀락, 뮤텍스, 세마포어를 포함한 모든 상황에서 스핀락인 test_and_set 함수를 이용해 대기를 하신게 맞을까요?
우선 test_and_set은 atomic하게 동작하도록 CPU에서 제공하는 명령어(instruction)라고 생각하시면 됩니다~ 그리고 test_and_set을 제공하지 경우에는 다른 atomic operation을 사용해서 구현합니다
그리고 코드 관련 질문은 제가 정확히 답변드리기가 어렵네요 ㅠ
그냥 사용해도 될 것 같긴 한데 정확한 것은 저도 해봐야 알 것 같습니다
안녕하세요 영상 잘 보았습니다. 학습에 큰 도움을 받았어요 감사드립니다.
스핀락은 멀티 프로세서에서만 사용할 수 있다는 내용을 본 적이 잇는데요 아무리 생각해봐도 잘 이해가 안되는데 혹시 설명해주실 수 있나요?
=====================
영상 중간에 싱클 코어에서는 busy waiting 중인 프로세스를 깨울 cpu가 없으니 비효율적이라서 다중 프로세서에서만 사용한다고 이해하면 될까요?
영상 좋게 봐주셔서 감사합니다 :)
조금 더 정확히 워딩을 하자면
'싱글코어에서는 스핀락을 쓰는게 뮤텍스를 쓰는 것에 비해서 전혀 이점이 없고, 멀티 코어에서 그나마 이점이 있을 수 있다'는 의미고요,
왜 그럼 싱글 코어에서는 이점이 없냐면
스핀락을 쥐려고 busy waiting을 하는 프로세스(A)가 스핀락을 쥐려면, 우선 이미 그 스핀락을 쥐고 있는 프로세스(B)가 스핀락을 반환을 해줘야 하는데,
싱글 코어에서는 B가 스핀락을 반환을 하려면 일단 B가 코어에서 실행이 되어야 하기 때문에, 그렇다면 아무리 A가 현재 busy waiting 하고 있어도, 결국은 B로 컨텍스트 스위칭을 해서 B가 스핀락을 반환하고 나중에 다시 A로 컨텍스트 스위칭 되면 그때야 비로서 A가 스핀락을 쥘 수 있습니다
그렇다면 결국 스핀락으로 busy waiting 하는 목적이 최대한 빨리 락을 쥐기 위한 건데 싱글 코어에서는 busy waiting 해봤자 락을 빨리 쥘 수 없으니까 그럴바에야는 뮤텍스를 써서 A는 busy waiting 하지 않고 waiting 상태로 전환하고, A가 busy waiting으로 소비할 뻔했던 CPU 시간은 다른 C나 D 프로세스가 사용할 수 있도록 하는 거죠
@@ez. 상세한 설명 감사합니다. 무언가를 처음 이해하는데 시간이 오래 걸리는 편인데 간략하고 쉽게 설명해주셔서 감사해요
저도 처음 이해할 때 상대적으로 시간이 오래 걸리는 편이에요 :)
그래서 그런지 최대한 이해하기 쉽게 설명하려고 노력하게 되는 것 같아요
응원합니다 h h님 👍
안녕하세요. 강의 너무 유용하게 잘 듣고 도움 정말 많이 돼서 감사드립니다. 궁금한게 있는데 뮤텍스에서 가드를 TAS에 안 넣고, 벨류를 바로 TAS에 넣어 사용하면 안되는 건가요? TAS가 공유자원 상호배제하기 위해 사용하는 거고, 벨류를 상호배제하기 위해 가드를 TAS에 넣으면 그냥 벨류를 TAS에 넣어 바로 사용하면 안되나 라는 생각이 들어서요 ㅎㅎ 추가로 뮤텍스나 세마포어에서 슬립에 들어가는 건 OS에서 해주는건지 큐에 넣고 다음에 어떻게 진행되는 건지 궁금합니다.
안녕하세요~! 먼저 영상을 좋게 봐주셔서 감사합니다 :)
질문 주신 내용에서 TAS 관련된 부분은, 만약에 guard를 아예 안쓰고 value만 쓰게 되면 타이밍 이슈 때문에 정상적으로 동작하지 않을 수 있어요
뮤텍스 세마포 관련해서는, 리눅스 기준으로 말씀드리면 얘네들은 pthread 같이 OS의 API 형태(쉽게 말씀드리면 라이브러리)로 제공되는데요, 그 내부 구현을 보시면 락을 얻지 못할 때 어떻게 동작하고 또 나중에 어떻게 깨울지가 구현이 되어 있습니다. 그리고 그렇게 동작하는 와중에 OS의 시스템콜을 사용하는 부분도 있고요~
자세한 내용은 pthread mutex 구현 코드를 보시면 되는데요, C/C++에 익숙하시고 관심있으시다면 찾아보시는 것도 좋을 것 같아요 :)
@@ez. 답변 감사드립니다. 혹시 타이밍 이슈라는게 어떤걸지 알 수 있을까요? 그리고 타이밍 이슈는 가드를 사용 안하는 스핀락에서도 동일하게 나타나는 현상인가요?
답변 드리기에 앞서서 우선 양해를 구하고 싶은 부분이 있습니다ㅠㅠ
제가 여러 사정상 모든 댓글에 자세히 답변을 드리기 어려운 부분이 있습니다ㅠ
그래서 간단하게 설명을 드리거나 혹은 일부 답변을 드리지 못하는 부분이 있어도 이해를 부탁드리겠습니다 🙇♂️
---
예를 들어서 뮤텍스에서는 큐가 공유 자원이 되기 때문에 큐를 사용하는 코드를 mutual exclusion으로 보호해 주지 않는다면 큐가 이상하게 동작할 수 있습니다
스핀락에서는 큐를 사용하지 않기 때문에 이 문제가 없을 거고요
안녕하세요 ㅎㅎ 혹시 운영체제 관련해서 번역서 중에 추천해주실 만한 책 있을까요?
안녕하세요~ :)
제가 운영체제를 책으로 본 것은 학부 때 (공룡책으로 유명한) Operating System Concepts 라는 책이 전부에요~ 저는 원서로 봤는데 번역서가 있다면 번역 품질이 어떨지 모르겠어요~
이 책 말고는 따로 사본 책은 없구요, 틈틈히 구글링으로 많이 찾아봤던 것 같아요.
좋은 번역서 책을 추천드리면 좋았을텐데 아쉽네요 ㅠㅠ
리눅스api의 모든것
기초리눅스API
고급리눅스API
원도우 internal
원도우 api정복
영상 도움 받고 갑니다! 영상 보다보니 Mutex 정의가 락을 가질 수 있을 때까지 기다려라는 정의가 틀린것 같습니다.
Mutex라는 개념이 Lock Mechanism에 의해서 고안된 개념이고. Shared memory에 접근하게 위해서 System에 요청해서 Mutex를 받아, 주어진 task를 수행하는 것으로, Shared Memory에 접근 할 수 있게 권한을 얻는 것으로 보는 것이 맞는 것 같습니다. Mutex를 받을 수 없을 때, 기다리는 방식이 스핀락이랑 Queue 방식으로 나뉘는것 같구요.
영상 봐주셔서 감사합니다 :)
도움이 됐다니 뿌듯하네요ㅎㅎ
그리고 의견 주신 것도 감사합니다~!
영상에서 설명이 틀린 부분이 있다고 말씀해 주신 것 맞죠?
써주신 글이 제가 정확히 이해하기에 조금 모호하게 느껴지는 부분이 있어서요 ㅠ
그래서 답변을 길게 쓰게 됐는데 (오해없이 쓰려고 몇 번 수정도 했습니다ㅎㅎ) 정성들여 쓰다보니 길어진 거라서 놀라지 마시길요~👍
---
>> Mutex 정의가 락을 가질 수 있을 때까지 기다려라는 정의가 틀린것 같습니다.
: 혹시 영상 몇분 몇초 내용이 틀렸다고 생각하신 것인지 알려주시면 제가 더 정확히 답변드릴 수 있을 것 같습니다 ㅠ
지금 당장은, 그 당시에 'mutex는 락을 가질 수 있을 때까지 sleep 상태로 기다리는 것이 특징이다'로 설명했던 것 같습니다
>> Mutex라는 개념이 Lock Mechanism에 의해서 고안된 개념이고. Shared memory에 접근하게 위해서 System에 요청해서 Mutex를 받아, 주어진 task를 수행하는 것으로, Shared Memory에 접근 할 수 있게 권한을 얻는 것으로 보는 것이 맞는 것 같습니다.
: 뮤텍스를 권한으로 봐야한다는 주장이신거죠?
저는 '뮤텍스는 락을 얻는 혹은 락이 동작하는 메카니즘 중에 한 종류'로 보고 있고, 이걸 조금 더 추상화해서 설명하면 '뮤텍스는 락의 한 종류'로 볼 수도 있다고 생각합니다
참고로 저는 critical section에서 보장되야하는 mutual exclusion을 의미하는 MutEx와 락의 메카니즘으로서의 뮤텍스를 구분해서 보고 있습니다
>> Mutex를 받을 수 없을 때, 기다리는 방식이 스핀락이랑 Queue 방식으로 나뉘는것 같구요.
: 저는 개인적으로는 락이 동작하는 방식을 스핀락, 뮤텍스, 세마포, 모니터 이런식 으로 구분하는 것이 더 명확하고 이해하기 좋다고 생각해요
p.s. 댓글 주신 부분은 맞고 틀리고의 문제가 아닌 영역인 것 같은데, 틀린것 같다고 워딩을 해주신 부분은 개인적으로는 조금 아쉬웠어용 ㅠㅜ