말하고 싶었던 중요한 내용이 영상에서 하나 빠졌네요 ㅠㅠ (만들다보면 이따금 꼭 아쉬운 부분이 하나씩 생깁니당 ㅠㅠ) * 일반적으로 다른 수식어 없이 단순히 '스레드'라고 한다면 보통은 OS 스레드를 말하거나 OS 스레드와 1대 1로 매핑되는 유저 스레드라고 이해하시면 될 것 같아요 * OS와는 별개로 유저 레벨에서 자체적으로 관리되고 스케줄링 되는 스레드는, 유저 스레드 혹은 그린 스레드라고 불린다고 생각하시면 될 것 같아요 (지금까지 여러 문서들을 읽어봤을 때 주로 그랬습니다)
중간고사기간에 운영체제를 공부하다 os가아무리 암기 과목이라고 말하지만 ㅠㅠ 맥락이 너무너무 이해안가서 책만 읽다가, 이렇게 강의를 보게되었습니다! 태어나게된 이유 정의 예제 까지 너무 상세하게 설명해주셔서 연결이 되지않았던 개념들이 서로서로 연결이되어서 너무 이제 이해가 잘되요 ㅎㅎ 감사합니다!
스레드에 대해서 이해가 잘 가지 않아서 다른 분들에게 여쭈어보다가 이 영상을 알게 되어서 보게 되었는데.. 쉬운코드님 덕분에 스레드 개념을 잘 잡을 수 있게 된 것 같습니다 감사합니다!! 한 가지 궁금한 것이 있어서 질문드려봅니다! java의 경우 One-To-One 방식으로 유저 스레드와 OS 스레드가 매핑된다고 설명해주셨습니다. 그렇다면 스레드풀로 스레드를 100개를 만들게 되면 100개의 OS 스레드가 생성되어서 매핑되는 것이고 CPU가 4코어 8스레드인 하드웨어 스레드가 있을 경우 100개의 OS 스레드들을 실행시킬 때 100개의 OS 스레드들이 8개의 하드웨어 스레드들의 자원을 사용하면서 OS 스레드들이 변경될 때 발생하는 게 컨텍스트 스위칭이라고 이해가 되는데 맞게 이해한 게 맞는지 궁금합니다!!
오늘 용량 다쓴것 같습니다 하하 하드웨어 쓰레드 = cpu 그외 쓰레드 = s/w 유저 모드에서 구현되느냐 커널모드에서 구현 되느냐에 따라 나뉘고 이 둘을 어떻게 매칭 하느냐에 따라 또 나뉘고 한두개 따로 노는 애들이 또 있음 오우 좀 쉬어야 할듯 정말 감사합니다 하드웨어 쓰레드 저거이가 늘 가상머신 구현 할때 헷갈렸는데 여기서 이해 했습니다 Amd도 비슷하겠지요?
크 여기까지 달리셨군요~!! 멋있습니다 👍 맞습니다 좀 더 오해없이 정리하자면 - 하드웨어 스레드 = CPU 레벨에서 용어 - OS 스레드 = OS 레벨에서 용어 - user 스레드 = 프로그래밍 언어 혹은 프로그래밍 언어의 virtual machine에서 용어 (가령 JVM 같은) 이렇게 될 것 같아요~ 스레드 구분을 유저모드에서 구현되느냐 커널 모드에서 구현되느냐로 구분하는 것은 조금은 정확하지 않을 수 있는데요, 유저모드는 '유저가 작성한 코드'가 OS 스레드를 통해 CPU에서 바로 실행되는 모드이고, 커널모드는 유저가 작성한 코드의 요청에 의해 '커널에 존재하는 코드'가 OS 스레드를 통해 CPU에서 실행되는 모드입니다 그렇기 때문에 모드로 (스레드를 구분하기 보다는) 모드에 따라 유저 코드가 CPU에서 실행되는지 아니면 커널에 존재하는 코드가 CPU에서 실행되는지로구분하시는게 더 정확할 것 같아요 :) 참고로 커널 모드일 때도 유저 모드일 때도, OS 스레드와 유저 스레드는 모두 존재하고 있습니다 왜냐하면 (요즘은 멀티코어기 때문에) CPU의 각 코어에서 실제로 실행되는 것은 OS 스레드이고 그 OS 스레드를 개발자가 사용하기 쉽게 프로그래밍 언어 레벨로 추상화한 것이 유저 스레드이기 때문이죠 그리고 보통은 이 두 스레드가 1대 1 맵핑이지만 점점 1대 1 맵핑 외의 맵핑 형태로도 사용할 수 있도록 프로그래밍 언어들이 개발되고 발전하고 있습니다 끝으로, 맞아요 저도 AMD도 인텔과 비슷하다고 알고 있습니다 :)
@@ezcd 아하 그렇군요 모드에 따라 구분되는게 아니라 쓰레드가 os단계에서 실행이 되느냐 커널에서 실행되느냐에 따라 구분 되는거 군요 여기서 의문점이 유저모드에서 실행이 된다고 하지만 어짜피 시스템콜을 통해 커널에 요청을 하게 되면 이땐 어케 구분을 허허 아직 명확한 개념을 못잡다 보니 ㅠ 감사합니다
넵 맞습니다 :) 잘 이해하셨는데 오타를 내신 것 같지만 혹시나 하는 마음에 워딩을 정확히 하자면 >> '모드에 따라 구분되는게 아니라 쓰레드가 os단계에서 실행이 되느냐 커널에서 실행되느냐에 따라 구분 되는거 군요' 라고 써주신 이 부분을 정확히 하자면 '모드에 따라 구분되는게 아니라, CPU에서 실제로 실행되는 스레드냐 혹은 프로그래밍 언어 레벨로 추상화된 스레드냐로 구분되는 것'이 보다 더 정확한 표현일 것 같네요 참고로 OS의 핵심 기능을 담당하는 것이 커널이기 때문에 OS와 커널은 거의 유사한 개념이라고 보시면 됩니다 그리고 '실행'이라는 것의 의미는 'CPU에서' 실행을 의미하기 때문에 CPU에서 실제로 실행이 되는 것은 OS 스레드 입니다. 유저 스레드는, 이 OS 스레드를 추상화해서 프로그래밍 언어 레벨에서 개발자가 사용하기 편하게 포장된 추상화된 개념인 것이죠 그래서 '유저 스레드가 실행된다'는 표현은 엄밀히 말하면 '유저 스레드에 맵핑된 OS 스레드가 CPU에서 실행된다'라는 의미가 됩니다 이게 개념이 되게 헷갈릴 수 있습니다ㅠ 처음에 이걸 잘 이해하는게 (저도 그랬었고) 약간 난해할 수가 있어서 소화하는데 시간이 조금 필요해요 그래도 갈가마구님 항상 열정적으로 공부하시기 때문에 금방 이해하실 수 있을 것 같습니다 :) 그리고 시스템콜은 예를 들어 스레드 생성, 파일 I/O, 네트워크 I/O 같은 경우일 때 사용됩니다 그러므로 가령 아래와 같은 코드는 시스템콜과 상관 없는 부분이죠 int a = b + c; 항상 응원합니다 :)
2번을 봤습니다. 한 80% 이해를 한것 같습니다. 가장 어려 이해가 힘들었던 부분은 바로 유저 스래드 부분이었습니다. 이건 프로그램언어 차원에서 추상화 한것, 추상화란 개념을 이해 못해서 생기는 문제 였습니다. 유저 스래드는 자바라는 언어 차원에서 만든 관념적인, 실체가 아닙니다. 없는건데 있다고 우기는 겁니다. (실체가 없다는 의미 입니다.) 그래서 이걸 os 스래드와 매칭하는 방법에 대한 설명이 나오는 것이구요 항상 그렇지만 제 경우는 이놈의 추상화에서 상당히 애를 먹고 있습니다. 이게 어마 어마 하게 중요하고, 유용한 개념인 것을 최근에 서야 조금씩 알아 가고 있습니다. 시간이 되신다면 추상화에 대한것만 따로 강의 한번 부탁 드려도 될지 모르겠습니다. 잘못된 정보가 넘쳐 흐르는 세상에서, 등대를 만난것 처럼 기쁩니다. 감사합니다. 응원 하겠습니다. 지칠때도 있겠지만... 힘내세요 거듭 감사합니다.
맞습니다 점점 더 정확한 의미에 다가가고 계신 것 같아요:) 나머지 20%의 이해를 돕기 위해 저도 열정적으로(^^) 조금만 더 첨언을 하자면 우선 유저 스레드를 '실체가 없다' 는 표현은 듣기에 따라서는 반론이 나올 수도 있습니다 왜냐하면 가령 자바의 스레드나 파이썬의 스레드나 모두 각 언어에서 클래스의 형태로 개발자에게 제공하고 있고, 그래서 개발자가 실제로 사용하기 때문에 실체가 없다고 한다면 약간의 논란이 있을 수 있을 것 같아요 그렇지만 '실체가 없다'라는 표현이 한편으로는 맞는 표현인데요, 왜냐하면 CPU의 입장에서는 유저 스레드는 존재하지 않기 때문입니다 왜냐하면 CPU에서 실제로 실행되는 것은 항상 OS 스레드이기 때문에 CPU 입장에서는 유저 스레드의 존재 자체를 알 수가 없는 거죠 하지만 개발자는 개발하면서 OS 스레드를 다이렉트로 사용하기 보다는 프로그래밍 언어가 한번 포장하여 (혹은 재정의하여) 제공한 유저 스레드를 통해 OS 스레드를 사용하기 때문에, 유저 스레드가 개발자에게는 실체가 있는 존재여서, '실체가 없다'는 표현은 어떤 입장에서 보느냐에 따라 맞기도 하고 틀리기도 할 것 같아요 그리고 유저 스레드 개념은 자바에 국한된 개념은 아니고, 프로그래밍 언어 세계에서 일반화된 개념입니다 유저 스레드와 OS 스레드가 1대 1 맵핑일 때는 어차피 1대 1 맵핑이라 둘 다 퉁쳐서 스레드라고 주로 부르지만, 그 외의 경우에는 언어에 따라 코루틴, 고루틴 등등 다양한 용어로 불리게 됩니다 추상화와 관련된 영상은 기회가 되면 준비해볼게용 👍 끝까지 파고 들어가시는 모습 정말 멋있습니다!! 최고십니다!!
@@ezcd보이는데 보이지 않는 관점에 따라 있기도 하고 없기도 한 프로그램 이란걸 공부 하면서 점점 더 드는 생각이 왜 자꾸 철학적인 관점으로 연결 되는듯한 느낌입니다....극과 극은 통한다는 건지... 어디 프로그램으로 어디까지 갈 수 있을지...재밌을거 같습니다. 감사합니다
강의 너무 감사드립니다! 지금은 현업으로 돌아가셨지만 너무너무 잘 들었습니다. 질문이 하나 생겨서요! 유저 스레드의 컨텍스트 스위칭이 더 빠르다는 의미를 잘 이해하지 못 하겠습니다. 음 어찌되었든 컨택스트 스위칭이 일어나게 된다면 cpu의 캐시나 페이지 테이블이 변경되어야 하는데 같은 프로세스 내 스레드들만 묶어주게 되면 이런 것들이 발생하지 않으니 비용이 싸다는 의미인가? 로 이해했습니다. 혹시 비슷한 질문과 답변이 있지 않을까해서 덧글을 모두 읽어보니 ''' 그건 프로그래밍 언어가 어떻게 구현했는지에 따라 여러 방식이 있는데요, 가령 개발자가 직접 스위칭할 위치를 지정해 줄 수 있습니다. 그러니까 코드로 유저 레벨 스레드가 스위칭 해야할 위치를 명시할 수 있습니다. 예를 들어 피이썬의 코루틴이 이와 같은 방식으로 동작합니다. 파이썬의 코루틴은 유저레벨스레드이구요, async/await 문법을 통해 실행 중인 코루틴이 어느 위치에서 다른 코루틴으로 스위칭해야하는지 기술할 수 있죠 ''' 이렇게 답변하신 것이 있더라고요. 파이썬의 경우를 생각해보면 제가 생각한 것이 맞는 것 같은데 그럼 보통 many to one 모델은 하나의 프로세스에서 여러 스레드들을 사용하는 경우 사용한다라고 생각해도 될까요?
여러 프로세스를 메모리에 올려두고 io가 있을 때 다른 프로세스가 cpu를 점유하는 멀티 프로그래밍 기법과 하드웨어 하이퍼 스레딩이 유사해보이는데 맞나요..? OS가 소프트웨어적으로 하드웨어에서 제공하는 하이퍼 스레드를 지원하는 게 멀티 프로그래밍 기법으로 이해하는 게 맞을지 궁금합니다..!
좋은 강의 너무나 감사합니다!! 하드웨어 스레드와 os 스레드를 연결 지어서 생각해 보는데 뭔가 찜찜한게 남아 있어서 질문 드립니다!! 자바같은 경우 1 대 1로 os 스레드가 생성된다고 하는데 그럼 여기서 하드웨어 스레드 보다 더 많은 스레드가 생성된다면 영상에 나온 예처럼 이 스레드들은 동시에 실행이 안 되고 cpu할당 받기를 기다리는거죠? cpu스케줄링을 통해서??
영상 잘 보았습니다!, 한가지 궁금한점이 있습니다. one-to-many 모델을 사용할때 결국은 하나의 os thread에서 여러개의 user thread를 실행하는 것이기 때문에 동시에 실행될수가 없어서 절대로 race condition이 발생하지 않게 되는 것이 맞나요?
안녕하세요~!! 유익하게 봐주셔서 감사합니다 :) many-to-one 질문이신거죠? 답변 드리면 '절대로'는 아닐 수 있을 것 같고요, 왜냐하면 유저 스레드들이 어쨌든 유저 레벨에서 스케줄링 될 거라서 해당 모델을 어떻게 구현하는지에 따라서는 race condition이 발생할 가능성도 있을 것 같습니다~ 하지만 어쨌든 다른 모델들에 비해서는 발생할 여지가 상당히 적겠죠 이 부분에 대한 설명은 영상의 15:55에서도 간략하게 언급했으니 참고 부탁드려요 :)
안녕하세요. 높은 퀄리티의 내용을 쉽게 쉽게 전달해주셔서 진심으로 감사드려요. 정말 큰 도움이 되고 있습니다. :) 영상 내용 중에 궁금한 점이 있는데요. Java Thread model 관련해서 초기에 Java는 Many-to-One(Green thread) Model을 사용하다 Many-to-Many Model을 사용하는 것으로 알고 있었습니다. 즉, User Thread들의 스케줄링을 JVM이 해주는 것으로 알고 있었는데요. (Oracle reference를 통해 습득한 내용입니다.) 영상 내용을 보니 현재 Java가 사용 중인 모델이 One-to-One 모델이라고 하셔서요. 혹시 이 내용의 출처를 알 수 있을까요?? 자료를 찾아보니 그럴 수도 있겠다 싶은 내용은 있지만, 명확한 자료가 없어서 문의 드려요 ㅠ.ㅠ
반갑습니다 :) 영상을 좋게 평가해 주시고 유익하게 봐주셔서 정말 감사드려요 👍 질문주신 내용에 답변 드리겠습니당 우선 java가 many-to-many 모델이라고 말씀하신 부분의 오라클 레퍼런스가 아래 링크 비슷한 내용인가요? docs.oracle.com/cd/E19620-01/805-4031/6j3qv1oej/index.html 이런 종류의 글을 말씀하시는 거라면 이건 Solaris OS 한정으로 봐야할 것 같아요 기본적으로 자바는 threading model을 직접 JVM에서 관리하는 것이 아니라 그 아래 단의 OS에 위임을 합니다. 이건 소스코드를 보면 알 수 있는데요, jdk의 Thread 클래스의 소스코드를 보시면 start 메서드에서 start0메서드를 호출하는데요,, (아래 링크 691번 라인 참고) github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/lang/Thread.java#L691 이 start0는 private native void start0(); 로 되어 있습니다 (705번 라인) 여기서 native 키워드는 C나 C++ 처럼 다른 언어로 구현된 것을 호출하기 위해 사용되는 키워드이며, JVM은 이 키워드를 보고 JNI(Java native interface)를 통해 아래단의 OS 플랫폼에서 제공하는 라이브러리 메서드를 호출합니다 그렇기 때문에 OS 플랫폼에서 어떻게 라이브러리를 제공하는지 따라 one-to-one일 수도 있고 many-to-many일 수도 있습니다. 위 링크에서 Solaris OS의 경우에는 제공하는 라이브러리가 many-to-many로 동작하도록 구현됐기 때문에 many-to-many인 거고요, 하지만 우리가 가장 흔히 사용하는 윈도우나 리눅스 같은 경우에는 플랫폼 레벨에서 one-to-one model 방식으로 동작하도록 라이브러리를 제공합니다 구글링을 이미 해보셨지만 도움 되실 수 있게 몇 가지 링크를 걸어둘게요 👍 * 윈도우와 리눅스에서 java thread와 OS thread(혹은 kernel thread)는 one-to-one이라고 설명하는 글 : www.developer.com/design/an-introduction-to-jvm-threading-implementation/ * 비슷한 종류의 질문들에 대한 답변들 - stackoverflow.com/questions/17125101/one-to-one-mapping-of-java-thread-to-linux-thread-lwp - www.quora.com/Are-Java-threads-user-level-threads/answer/Robert-Love-1?ch=10&oid=2065330&share=39208bda&target_type=answer (참고로 이런 종류의 내용은 공식 문서에서 찾기 쉽지 않더라고요 ㅠ)
최근 영상이 아니고 여러모로 바쁘실거라 생각해서 문의 시 망설임이 많았었는데 ㅠ.ㅠ 빠르고 상세한 답변 진심으로 감사합니다. 👍👍 Oracle 레퍼런스는 위 자료가 맞습니다. Solalis OS에 대한 내용이였는데, Windows/linux에 대한 내용이 따로 없고 또 다른 자료들에서 Java의 기본 방식인 것처럼 설명을 하고 있어서 제가 잘못 이해를 한 거 같아요. 공식 문서를 통해 확실히 알고 싶었는데, 말씀대로 그런 내용을 찾기가 쉽지 않더라구요ㅠ.ㅠ 공유주신 자료가 매우 도움이 되었습니다~👍 혹시 몰라 JNI와 JVM의 소스 코드를 직접 확인해보니 OS 별로 분리 구현되어 있었고, 말씀대로 윈도우와 리눅스의 대해서 one-to-one 방식으로 동작하도록 구현이 되어 있었네요. 속이 시원합니다 :) hg.openjdk.java.net/jdk9/jdk9/jdk/file/00cd9dc3c2b5/src/share/native/java/lang/Thread.c hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/prims/jvm.cpp hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/runtime/thread.cpp hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/runtime/osThread.cpp hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/os/linux/vm/osThread_linux.cpp 운영체제 영상들을 몇 번씩 봤는지 잘 모를 정도로 여러번 보고 있는데, 개인적으로 정말 유익하고 많은 깨달음을 얻고 있습니다. 진심으로 감사드려요. 주변에도 널리 알릴게요 ㅎㅎ 그럼 수고하세요~!
@@beansroa2755 와 멋지십니다~! 처음 써주신 질문에서도 저를 배려해 주시는 마음이 느껴졌었는데, 두 번째 댓글도 이렇게 젠틀하고 나이스하게 써주셔서 기분이 참 좋으네요 👍 그리고 이렇게 꼼꼼하게 확인하시는 모습에 저도 좋은 자극을 받게 됐습니다 :) 영상들을 자주 봐주셔서 정말 감사해요!! 훌륭하신 개발자분들이 많이 나오길 바라는 마음에서, 그리고 컴공 공부하시는 분들이 조금이라도 더 편하게 공부하실수 있길 바라는 마음에서 영상을 열심히 만들고 있는데요, 이렇게 댓글 써주시면 정말 큰 힘이 되고, 다시 한번 달려가는 추진력을 얻게 되는 것 같습니다 👍👍👍 댓글 정말 감사합니다! 앞으로도 꾸준히 파이팅 할게요 !!
선생님 정말 좋은 강의로 가르쳐주셔서 감사합니다 궁금한 점이 생겨서 질문을 받아주시면 감사하겠습니다 저는 여태까지 유저레벨 소스코드는 유저레벨 스레드가 실행시켜주는 것이고 중간에 시스템콜을 호출하면, 커널의 코드는 커널레벨 스레드가 실행시켜 주는 것이라고 이해하고 있었습니다 예를 들면 #include int b( ) { return 5; } int main() { int a=b( ); // 이 부분은 유저레벨 스레드가 실행 시스템콜( ); // 이 부분은 커널레벨 스레드가 실행 } 으로 알고 있었습니다 그런데, 강의 7분 20초에서 커널레벨 스레드가 사용자 코드와 커널 코드 모두 개입한다고 말씀해주셔서요 그러면 int a=b( ); 이 코드도 유저레벨 스레드가 아닌 커널 레벨 스레드가 개입하는건지 궁금해서 여쭙고 싶습니다 질문 읽어주셔서 감사합니다 그리고 좋은 강의를 올려주셔서 정말 감사드립니다
안녕하세요~ 먼저 영상에 대해 좋게 봐주셔서 감사합니다 :) 선생님이라뇨ㅠㅠ 몸둘 바를 모르겠습니당 ㅎㅎ 질문 주신 것에 답을 두괄식으로 드리면 말씀하신 것처럼 int a = b(); 이 코드도 결국 커널 레벨 스레드에 의해 실행된다고 보시는 것이 맞습니다. 조금 더 자세히 설명을 드리면, 'CPU에서 실행'이라는 관점에서 생각해보면 좀 더 쉽게 이해하실 수 있는데요, CPU와 프로그램의 인터페이스 역할을 하는 것이 OS이고 CPU 등의 하드웨어 입장에서는 운영체제만 바라보기 때문에 OS 스레드(혹은 커널레벨 스레드)가 있어야만 CPU에서 실행될 수 있습니다. 즉, 개발자가 작성한 프로그램이 CPU에서 실행된다는 것은 개발자가 작성한 코드들은 OS 스레드에 담기게 되고, CPU에서는 OS 스레드에 담긴 개발자가 작성한 유저 레벨 '코드'나 혹은 시스템 콜 같은 커널 레벨 '코드'가 실행된다는 의미이기 때문에 CPU에서 코드가 실행되기 위해서는 OS 스레드가 반드시 필요합니다. 그럼 유저 레벨 스레드라는 것은 무엇이냐면, 프로그래밍 언어 레벨에서 정의하거나 혹은 추상화한 스레드라고 생각하시면 이해하시는데 도움이 될 것 같습니다. 예를 들어 자바나 파이썬(CPython) 같은 경우를 보면 각각 스레드라는 클래스가 있는데요, 이를 바탕으로 스레드를 하나씩 만들 때마다 OS 스레드도 하나씩 만들어지는 1대 1 맵핑 관계입니다. 자바나 파이썬 언어를 설계하고 만든 사람들의 철학이, 그들의 세계관에서는 자신들의 스레드를 OS 스레드와 1대 1로 연결시키기로 정의한 거죠. 즉, 이들 언어의 스레드 정책은, 그 언어에서 스레드를 사용한다는 것은 곧 OS 스레드를 사용한다는 것으로 만들어버린 것입니다. 아마 대부분의 프로그래밍 언어에서 스레드라고 하면 OS 스레드와 1대1로 맵핑되는 구조일 것 같구요, 영상에서 설명했던 것처럼 1대1 맵핑 말고도 다대일 맵핑, 다대다 맵핑 등등 여러 형태의 맵핑 방식이 있는데, 이런 경우에 유저 레벨 스레드는 스레드라고 부르기 보다는 각각 독립적인 네이밍(가령, 그린스레드, 코루틴 혹은 고루틴 등등)을 쓰는 것 같아요. 어쨌든 핵심은 유저 레벨의 스레드는 각 프로그래밍 언어의 철학에 따라 프로그래밍 언어 레벨에서 추상화된 스레드이며 이들 스레드가 실제로 CPU에서 실행되기 위해서는 CPU는 OS를 통해서만 소통(?)하기 때문에 반드시 OS 스레드와 연결되어야 한다는 점, 그래서 실제로 CPU에서 실행될 때는 OS 스레드에 의해 실행된다고 이해하시면 될 것 같아요~
@쉬운코드 선생님 정말 상세한 가르침을 주셔서 고맙습니다 제가 혹시 제대로 이해했는지 봐주시면 정말 감사하겠습니다 1. 시스템콜의 코드는 커널레벨 스레드가 실행시킵니다. 커널모드에서 동작하는 스레드이기 때문입니다 2. 유저레벨의 코드를 실행시킨다는 것은 유저모드에서 동작하는 것을 의미합니다 그러나, 유저모드에서는 유저레벨의 스레드만 동작하지 않습니다 유저레벨의 코드가 실행되려면 , 유저레벨스레드와 커널레벨스레드 모두 필요합니다 그 이유는, 유저레벨의 코드 예를 들면, int a = b(); 또는 라이브러리 함수들은 유저레벨 스레드가 실행시키긴 하지만, 실제로 프로세스가 실행되려면 CPU를 점유해야 하는데 실제로 CPU를 점유하는 스레드는 커널 레벨 스레드이기 때문입니다. 따라서, 유저레벨의 소스코드를 실행시킬 경우에는 유저레벨스레드와 커널레벨스레드가 같이 작동합니다 3. 다 대 일 모델의 문제가 여기서 이어집니다 다 대 일 모델에서는 유저레벨스레드가 5개여도, 결국, 유저레벨스레드 1개가 실제로 실행이 되려면 CPU를 점유하고 있는 커널레벨스레드 1개와 연결이 되어야 합니다 유저레벨 스레드 5개 중 1개가 커널레벨스레드를 점유하고 있으면 나머지 4개 유저레벨 스레드들은 놀고 있습니다 4. 같은 원리로 다 대 일 모델에서는 커널 레벨 스레드 하나가 blocking 되면, 유저레벨스레드들도 중단하게 됩니다 라고 이해했는데, 혹시 번거로우시겠지만, 이렇게 이해해도 되는지 봐주시면 감사하겠습니다 좋은 강의 들려주시고, 정말 상세하게 가르쳐주셔서 감사합니다 ㅠㅠ
@@light8013 오~! 거의 비슷합니다~! 조금만 더 정확하게 설명을 드려볼게요. :) 우선 용어 정리부터 다시 명확히 하자면, 커널 레벨 스레드(=OS 스레드)는 커널에서 관리하는 스레드, 즉,CPU 스케줄링의 대상이 되는 스레드, 실제로 CPU에서 실행되는 스레드이며 유저 레벨 스레드는 개발자가 프로그래밍 언어로 부터 제공받는, 각 프로그래밍 언어 세계관에서 존재하는 '관념적인' 스레드라고 이해를 하시면 되겠습니다 즉, 유저 레벨 스레드는 프로그래밍 언어 레벨에서 언어의 철학에 맞게 '추상화한 개념'이라고 이해하시는게 제일 정확한 것 같습니다. 스레드를 프로그래밍 언어 관점에서 보느냐, 아니면 OS나 CPU의 관점에서 보느냐에 따라 유저 레벨 스레드로 보느냐, 커널 레벨 스레드로 보느냐로 나눠지는 부분이라서 유저 레벨 스레드와 커널 레벨 스레드를 대등한 위치에 놓고 비교하기에는 조금 어려움이 있습니다. 예를 들어, 자바로 코드를 작성해서 실행해보면, 개발자가 작성한 자바 코드는 (개발자가 명시적으로 자바 스레드를 만들지 않았어도) 하나의 자바 스레드 위에서 실행이 됩니다. 여기서 이 자바 스레드는 자바 언어가 정의한 자바의 '유저 레벨 스레드'입니다. 그리고 자바는, 언어 정책 상, 자바 스레드와 OS 스레드를 1대1로 맵핑시켜서 사용합니다. 결국 개발자가 작성한 자바 코드는 자바 스레드에서 실행되지만 최종적으로 OS 스레드에 의해 CPU에서 실행이 될 겁니다. 그러면 이 때 사용자가 작성한 코드는 자바 스레드(= 자바의 유저 레벨 스레드)에 의해서 실행되는 것일까요? 아니면 OS 스레드(=커널 레벨 스레드)에 의해 실행되는 것일까요? 이 질문을 유저 레벨 스레드와 OS 스레드를 같은 위치에서 동등하게 놓고 이해하려면 헷갈릴 수 있는데요, 이 문제는 스레드를 어떻게 바라보느냐라는 관점의 문제이기 때문입니다. 프로그래밍 언어 혹은 그 언어를 사용하는 개발자 관점에서 보면 해당 코드는 자바 스레드(=유저 레벨 스레드)에서 실행된다고 볼 수 있습니다. 반면에 OS 관점에서 혹은 CPU 관점에서 보면 해당 코드는 OS 스레드에서 실행된다고 볼 수 있습니다. 이런 맥락에서 질문주신 내용에 답변을 드리자면 1.커널 레벨 스레드(OS 스레드)가 실제로 CPU에서 실행되는 스레드이기 때문에 시스템콜의 코드는 커널 레벨 스레드에서 실행이 됩니다. 그리고 (아마 이해하시고 계시겠지만) 커널 레벨 스레드는 커널 모드에서만 동작하는 스레드는 아닙니다. 스레드의 생성과 실행/관리를 커널이 주관한다는 의미에서 커널 레벨 스레드라고 부르는 것이지, 커널 모드에서만 실행한다는 의미는 아닙니다. 유저 모드에서 실행되는 유저 레벨의 코드들도 (CPU 관점에서 보면) 커널 레벨 스레드에서 실행됩니다. 여담이지만 저는 개인적으로 커널 레벨 스레드라는 용어보다는 OS 스레드라는 용어가 좀 더 좋다고 생각하는데요, 커널 레벨 스레드라고 하면 마치 커널 모드에서만 실행될 것 같은 느낌을 주기도 하고, 비슷한 이름이지만 다른 의미를 가지는 커널 스레드라는 용어가 존재하기 때문입니다. 2. 유저 레벨 스레드와 커널 레벨 스레드는 관점의 차이에서 비롯된 개념이라는 것만 잘 이해하셨다면 말씀하신 내용이 맞습니다. 유저 레벨 스레드는 개발자에게 제공되는 추상화된 혹은 관념적인 개념임을 잘 이해해주시는게 핵심일 듯 싶네요. 3. 맞습니다 :) 물론 여기서 논다는 개념은 CPU를 사용하지 못한다는 개념일거구요~ 4. 역시 맞습니다. 첨언을 드리자면, 커널 레벨 스레드가 블락이 된 이유는 유저 레벨 스레드 중에 하나에 블락킹 코드가 있었고 그 코드가 커널 레벨 스레드에서 실행되다가 커널 레벨 스레드가 블락됐을 거라고 짐작해볼 수 있죠. 제가 육아를 하러 가야해서 혹시 여전히 헷갈리시면 댓글 남겨주시면 늦은 밤에 답변 드릴게요 :)
@쉬운코드 선생님 이렇게 자세하고 상세하게 가르쳐주셔서 감사합니다 정말 너무 고맙습니다(꾸벅) 선생님 덕분에 궁금했던 부분들이 거의 다 이해가 되는 것 같습니다 ㅠㅠ 사용자 레벨 쓰레드가 추상적이고 관념적인 개념이라는 말씀에서 추상적이고, 관념적인 것에 대해 생각하다가 제가 바보라서 혹시 이렇게 이해해도 되는지 여쭙고 싶습니다 1. 다 대 일 관계를 보면 아무리 사용자 레벨 쓰레드들이 많아도 cpu 입장에서는 싱글코어에 os 쓰레드 하나만 연결되어 있으니 cpu 입장에서도 싱글 쓰레드로 보이고 실제로 일을 하는 것은 싱글 쓰레드입니다 2. 사용자 영역의 프로세스에 아무리 많은 쓰레드들이 있어도 커널 입장에서는 os의 싱글 쓰레드에 연결된 사용자 프로세스 하나가 있을 뿐입니다. 3. 개발자가 유저 레벨 라이브러리로, 유저 레벨 쓰레드를 멀티 쓰레드로 구현하면 이 유저레벨쓰레드들은 cpu를 점유하기 위해 경쟁할 것입니다 4. 그러나, 실제로는 cpu와 연결된 os 쓰레드가 코드를 실행시키기에 (사용자 레벨 코드든, 커널의 코드든 os 쓰레드가 실행시킵니다.) 5. 결국, 사용자 레벨 쓰레드들이 cpu를 점유하기 위해 경쟁한다는 것은 cpu를 실제로 점유한 os 쓰레드와 연결되기 위해 경쟁한다는 것입니다 6. 결국 다 대 일 모델은 cpu나 커널의 관점에서는 싱글 코어와 싱글 쓰레드가 일을 하는 것입니다 7. 사용자 레벨 쓰레드들 중 하나가 cpu를 점유해서 자신의 코드를 실행했다는 의미는 . 실제로는 cpu를 점유하고, 실제로 일하는 os 쓰레드가 해당 사용자 레벨 쓰레드가 실행하기로 약속한 실행코드를 os 쓰레드가 대신 실행해주었다는 것입니다 라고 이해했습니다 선생님 선생님 정말 고맙습니다
@@light8013 어유 바보라니요 열심히 하시는 모습 멋지십니다~! 유저 레벨 스레드가 추상화 혹은 관념적 개념이라는 의미는 이렇게 이해하시면 어떨까요? 예를 들어 리눅스라는 OS는 C언어 기반으로 짜여져 있습니다. 이제 이 리눅스 위에서 동작하는 프로그램을 개발하려면 우리는 프로그래밍 언어 하나를 골라서 개발을 하게 되는데, 예를 들어 자바라고 해보겠습니다. 자바로 개발을 하다가 스레드를 사용하고 싶어졌습니다. 그럼 개발자는 자바가 제공하는 자바 스레드를 사용하여 개발할 수 있습니다. 이제 이 프로그램을 리눅스에서 실행하면 잘 동작하는 것을 확인할 수 있습니다. 잘 동작한다는 것은 결국 CPU 관점에서 생각해보면서 리눅스의 OS 스레드에서 코드가 실행됐다는 것인데, 여기서 재밌는 점은 자바에서 제공하는 자바 스레드로 개발했을 뿐임에도, 어떻게 리눅스의 OS 스레드가 실행되냐라는 점입니다. 오직 자바로만 개발했고, C언어로는 개발하지 않았음에도 어떻게 C언어로 개발된 리눅스 OS 스레드를 사용할 수 있게 된 것일까요? 그것은 자바라는 언어가 OS 스레드를 추상화하여 자바 스레드라는 형태로 개발자에게 제공을 했기 때문입니다. 여기서 자바 스레드는 유저 레벨 스레드이지만 자바라는 언어의 스레드 정책은 자바 스레드와 OS 스레드를 1대 1 맵핑 시키기 때문에 결국 OS 스레드를 사용하는 것과 똑같아 지는 것이죠. 반면 자바의 아주 초창기 모델은 이런저런 이유들로 (그린스레드라고 해서) 자바 스레드를 여러개 만들어도 OS 스레드 하나와 맵핑되는 다대일 구조였습니다. 즉, 초창기 자바 버전에서는, 자바 개발자가 자바 스레드를 여러개 만들어 개발을 해도 실제로 OS 레벨에서는 하나의 스레드에 맵핑이 됐기 때문에, 여러 자바 스레드가 하나의 OS 스레드를 두고 서로 번갈아가며 실행되는 형태였었죠. 이제 이런 맥락에서 질문주신 내용을 좀 더 매끄럽게 정리해보겠습니다. 1. 다 대 일 관계를 보면 아무리 사용자 레벨 쓰레드들이 많아도 cpu 입장에서는 (싱글코어인지 멀티코어인지는 중요하진 않습니다) os 스레드 하나와 연결되기 때문에 cpu 입장에서는 싱글 OS 쓰레드로 보이고 실제로 CPU에서 실행되는 것은 싱글 OS 쓰레드입니다 2. 요건 정확히 어떤 것을 의도한 질문인지 잘 모르겠습니다ㅠㅠ. 스레드와 프로세스에 관한 질문인가요? 요건 또 다른 주제라 일단 패스할게요 3~5. (한번에 쓸게요) 다 대 일 관계에서는 개발자가 유저 레벨 쓰레드를 여러개 만들면 이 유저레벨쓰레드들이 cpu를 점유하기 위해 경쟁하는 것처럼 생각할 수도 있지만 그러나 엄밀히 말하면 실제로 cpu에서 실행되는 것은 os 쓰레드이기 때문에 (OS 스레드가 코드를 실행'시킨다'는 것은 약간 저는 어색합니다. OS 스레드에 코드가 포함되어 있고 그 OS 스레드가 스케줄러에 의해 선택되어 디스패처에 의해 CPU에 디스패치되면 그 코드들이 실행이 되는 거라서 시킨다는 느낌은 저는 조금 어색하더라구요 ㅠ) 결국, 사용자 레벨 쓰레드들이 cpu를 점유하기 위해 경쟁한다는 것은 cpu에서 실제로 실행되는 os 쓰레드와 연결되기 위해(혹은 os 쓰레드를 점유하기 위해) 스케줄링(제 개인적으로는 경쟁보다는 스케줄링이라는 표현이 더 적절할 것 같아요) 되는 것을 의미합니다. 6. 결국 다 대 일 모델은 cpu나 커널의 관점에서는 (코어 갯수는 상관없는 부분입니다) 싱글 OS 쓰레드가 실행되는 것입니다. 7. 다 대 일 모델에서는 사용자 레벨 쓰레드들 중 하나가 cpu를 점유해서 자신의 코드를 실행했다는 의미는 실제로는 cpu에서 실행되는 os 쓰레드가 해당 사용자 레벨 쓰레드가 담당하는 실행코드를 (대신) 실행했다는 의미가 됩니다 참고로 일반적으로 '스레드'라고 하면 OS 스레드, 혹은 OS 스레드와 1대 1로 맵핑되는 유저 레벨 스레드라고 생각하시면 될 것 같습니다. (물론 언어에 따라 잘 파악해야겠지만 저는 지금까지 이렇게 이해해도 어려움이 없었습니다) 다대일 모델이거나 다대다 모델일 때는 유저 레벨의 스레드를 지칭하는 별도의 네이밍을 언어마다 정해서 쓰더라구요.
안녕하세요 선생님 꿀같은 강의 감사합니다 ㅎㅎ 궁금한 점이 있는데요 1. OS 스레드는 OS가 스케줄링하여 CPU를 할당하는 게 맞을까요? 2. 그럼 다대다 혹은 다대일처럼 여러 개의 유저 스레드가 OS 스레드에 할당되어야 하는 경우에는 유저 스레드 - OS 스레드 간에 스케줄링은 누가 담당하나요? 혹시 영상에 이미 나온 내용이라면 죄송합니다 ㅠㅠ
아이쿠 선생님이라뇨 과찬이십니다 ㅠㅠ ㅎ 그저 같은 길을 걸어가는 같이 성장하고픈 개발자로 봐주세요 ㅎㅎ 1. 네 맞습니다!! 2. 저는 유저 스레드의 개념을 넓게 보는데요, 그렇기 때문에 유저 스레드를 누가 스케줄링 하느냐 했을 때 크게 두 가지로 답변할 수 있을 것 같습니다 첫째는, 언어가 제공하는 virtual machine이 담당합니다 대표적인 예가 아주 초창기 자바 버전에서는 green thread가 있었는데 예가 유저 스레드입니다 그리고 이 친구들의 스케줄링을 담당하는 것은 java virtual machine이고요 둘째는, 개발자가 직접 프로그래밍 언어를 통해 언제 컨텍스트 스위칭이 일어나는지 명시하는 방법입니다 프로그래밍 언어는 스위칭할 타이밍을 지정할 수있게 문법을 제공하고 개발자는 그 문법을 활용해서 스위칭 할 위치를 명시하는 형태인데요, 오늘날 이 형태가 메인 패러다임이 되고 있습니다 즉, 스케줄링 위치를 개발자가 직접 언어가 제공하는 문법으로 챙기는 거죠 코루틴이 이렇게 동작합니다
그건 프로그래밍 언어가 어떻게 구현했는지에 따라 여러 방식이 있는데요, 가령 개발자가 직접 스위칭할 위치를 지정해 줄 수 있습니다. 그러니까 코드로 유저 레벨 스레드가 스위칭 해야할 위치를 명시할 수 있습니다. 예를 들어 피이썬의 코루틴이 이와 같은 방식으로 동작합니다. 파이썬의 코루틴은 유저레벨스레드이구요, async/await 문법을 통해 실행 중인 코루틴이 어느 위치에서 다른 코루틴으로 스위칭해야하는지 기술할 수 있죠
user space 코드를 실행하는 스레드와 실행하다가 인터럽트 또는 시스템콜이 발생했을때 kernel 코드를 실행하는 스레드는 모두 os 스레드로 동일한건 이해했는데요 user space 코드와 kernel space 코드를 실행하는 스레드는 다른 스레드인가요? (즉, 인터럽트 또는 시스템 콜 발생시 똑같은 스레드에서 실행되는게 아니라 스위칭이 일어나는지)
강의 잘 봤습니다~ 항상 강의를 들으면서 느끼지만 개념마다 적절한 예시를 들면서 설명해주셔서 이해하기 쉽네요. 오늘도 질문이 생겨서 댓글 남깁니다! 강의 내용을 실제 프로그램이 실행되어 프로세스 상태일때 어떻게 적용시킬 수 있을까 고민하다보니 아래와 같은 궁금점이 생겼습니다. 프로그램이 실제로 실행되어 프로세스가 되면, 프로세스마다 각자 가상메모리를 갖게되는 것으로 알고 있습니다. 프로세스의 가상메모리 안에는 프로세스가 실행되기 위한 여러 정보들이 저장되어있을 것이고, 크게 4가지로 분류하여 코드, 데이터, 스택, 힙이 있다고 알고 있는데, 가상메모리 안에는 저 4개의 영역을 제외하고, 커널을 위해 예약된(reserved) 영역이 있다고 알고 있습니다. 1. 그렇다면, 한 프로그램 내에서 만약에 유저모드에서 일반적인 코드를 실행할때는 os 스레드가 가상메모리의 코드 영역에서 명령어를 fetch 해와서 cpu에서 실행하는 것이고, 만약 시스템콜이나 io같은 커널레벨의 코드를 실행해야하는 경우에는 위에서 언급한 커널을 위해 예약된 영역에 해당 시스템콜이나 io를 위한 코드가 저장되어 있기 때문에, 그 부분에 os 스레드가 접근하여 cpu로 실행하는 것인가요? 2. 강의의 맨 마지막의 kernel thread를 cpu에서의 연산을 위해 사용되는 os 스레드와 혼동하지 않기 위해 'os커널의 역할을 수행하는 스레드' 라고 설명해주셨는데, 구체적으로 os커널의 어떤 역할을 수행하는 것인가요? 실제 os 커널이 수행하는 스케쥴링, 자원관리, 감시 등과 같은 것들을 말하는 것인지, 아니면 질문 1번에서 유저프로그램이 시스템콜이나 io같은 커널레벨의 코드를 실행해야하는 경우에 이를 수행해주는 정해져있는 kernel thread라는게 있는 건지 궁금합니다. 좋은 퀄리티의 강의 감사합니다.
세승님 항상 강의를 좋게 봐주시고 또 열심히 봐주셔서 정말 감사합니다 :) 질문도 항상 이해하기 좋게 말씀해 주셔서 저도 여러모로 도움이 되네요 이것도 감사합니다 👍 1. 네, 맞습니다~ 말씀하신 내용을 저의 언어로 동일하게 표현해 보자면, 시스템 콜(I/O 작업도 시스템 콜을 통해 가능하다고 저는 알고 있습니다)을 실행해서 커널 코드가 실행되는 경우에, OS 스레드가 가상 메모리 공간에 있는 커널 스페이스에서 코드를 fetch 해서 CPU 코어에서 실행됩니다 2. 네, 첫번째로 말씀해주신 부분(>> "실제 os 커널이 수행하는 스케쥴링, 자원관리, 감시 등과 같은 것들을 말하는 것인지")이 맞습니다 강의 준비하면서 구글링을 해보니 하드웨어 이벤트 모니터링이나 디스크와 RAM 사이에 데이터 이동 등등의 커널이 하는 핵심 역할을 백그라운드에서 데몬처럼 수행하는 스레드를 커널 스레드라고도 하더라고요 그래서 혼란을 피하기 위해서, 흔히 os에서 관리하는 개발자가 쓸 수 있는 스레드를 OS 스레드, 혹은 native 스레드라고 부르는게 좋겠다 싶었어요 (이 문장은 다른 분들도 보실 수 있어서 참고로 남기는 건데요) 개발자가 작성한 코드가 실행되다가 시스템콜을 통해 커널 코드를 실행하게 될 때도, 그리고 다시 돌아와서 개발자가 작성한 코드를 실행하게 될 때도 모두 한 OS 스레드 안에서 처리됩니다
@@ezcd 감사합니다! 답변해주신 답을 토대로 질문 하나만 더 드리겠습니다 ㅎㅎㅎㅎ 1번의 답변중 커널 스페이스라고 불리는 가상메모리의 일정 reserved된 공간에 관한 내용에 대해서 공부를 해보려면 참고할만한 자료가 있을까요? 컴퓨터에 존재하는 모든 프로세스는 동일한 커널을 통해 커널단의 기능을 사용할테고, 그럴 경우에 커널 스페이스에 들어가있는 데이터가 모두 똑같을 것 같은데, 그러면 추후에 이를 실제 물리 메모리에 올려서 연산에 이용할때 중복으로 인해서 생기는 오버헤드가 있을 것 같아서요. 물론 이에 대한 해결책도 이미 마련되어있을 것 같구요! 위와 같은 주제로 다양한 공부할 내용이 있을 것 같은데, 혼자서 찾아서 검색해서 공부하려고 하니, 어떤 키워드로 접근을 해야 알맞은 정보를 얻을 수 있을지 의문이라 질문드립니다 ㅠㅠ
공유할만한 글을 찾아봤는데, 뭔가 깔끔하게 정리된 글은 잘 안보이네요.. ㅠㅠ 우선 답변을 드리면 >> 그럴 경우에 커널 스페이스에 들어가 있는 데이터가 모두 똑같을 것 같은데, 그러면 추후에 이를 실제 물리 메모리에 올려서 연산에 이용할때 중복으로 인해서 생기는 오버헤드가 있을 것 같아서요. 물론 이에 대한 해결책도 이미 마련되어있을 것 같구요! 네, 맞습니다~ 첨언을 하자면 '커널 코드나 커널 코드 동작에 필요한 커널 데이터가 물리 메모리에 있다라고 한다면, 프로세스의 가상 메모리 공간의 커널 스페이스가 이 물리 메모리에 맵핑되는 형태로 동작한다'고 저는 이해를 하고 있어요. 그렇기 때문에 프로세스마다 커널 코드나 커널 데이터를 각자의 가상 메모리 공간의 커널 스페이스에 맵핑하는 형태로 '공유해서' 사용하기 때문에 중복된 코드나 데이터가 발생하지는 않을 것 같고요, 하지만 공유해서 사용하기 때문에 여러 프로세스가 같은 커널 코드를 우연히 동시에 실행했을 때, 이때 발생하는 데이터들은 프로세스 마다 자신들의 영역에 따로 저장을 해야할 것 같은데, (이 부분은 저도 아직 확실한 레퍼런스를 찾지는 못했고요,) 제 생각은 각자의 커널 스페이스에 일단 두지 않을까 싶어요. 그리고 유저 코드로 전달해야 하는 데이터라면 유저 스페이스로 복사하는 형태로 사용하지 않을까 짐작을 해봅니다 :) -- 요건 여담인데요, 보통 구글링은 한국어를 주로 하시나요? 아니면 영어로 주로 하시나요?
말하고 싶었던 중요한 내용이 영상에서 하나 빠졌네요 ㅠㅠ (만들다보면 이따금 꼭 아쉬운 부분이 하나씩 생깁니당 ㅠㅠ)
* 일반적으로 다른 수식어 없이 단순히 '스레드'라고 한다면 보통은 OS 스레드를 말하거나 OS 스레드와 1대 1로 매핑되는 유저 스레드라고 이해하시면 될 것 같아요
* OS와는 별개로 유저 레벨에서 자체적으로 관리되고 스케줄링 되는 스레드는, 유저 스레드 혹은 그린 스레드라고 불린다고 생각하시면 될 것 같아요 (지금까지 여러 문서들을 읽어봤을 때 주로 그랬습니다)
돌고돌아 이 채널로 오면 항상 깔끔하게 정리돠어있네요.....
OS공부하다가 이해가 안 돼서 막히고 답답할 때가 많았는데 선생님 동영상들 하나씩 보면서 매번 무릎을 탁!! 치고 갑니다 좋은 동영상들 올려주셔서 정말 감사하고 앞으로도 잘 공부하겠습니다.
아이쿠 선생님이라뇨 송구합니다 ㅠㅠ 그래도 영상들이 도움이 되고 있다니 저도 많이 뿌듯하네요 :)
계속해서 좋은 퀄리티의 영상으로 도움드릴 수 있도록 저도 열심히 하겠습니당~ 👍
17:49 many to many를 보니 project loom이 떠오르네요!!
와... 3개월전에 프로세스 관련 강의듣고 하드웨어랑 sw 쓰레드 관련 댓글 남겼었는데 다음 강의가.... 쓰레드 강의였군요 감사합니다
오 맞아요~ 이 부분이 오늘날 프로그래밍에서 중요한 부분이라 영상으로 다루게 됐습니당 ㅎㅎ 댓글 감사합니다 :)
그대가 최고입니다. 감사합니다.
와우!!! 구독자님도 최고십니다!!!
도움이 많이됩니다. 강의 다 듣고 홍보한번 해드리겠습니다..
크ㅠㅠㅠㅠ 홍보 정말 감사합니다!! 저도 꾸준히 좋은 영상으로 보답할게요!!👍
중간고사기간에 운영체제를 공부하다 os가아무리 암기 과목이라고 말하지만 ㅠㅠ 맥락이 너무너무 이해안가서 책만 읽다가, 이렇게 강의를 보게되었습니다! 태어나게된 이유 정의 예제 까지 너무 상세하게 설명해주셔서 연결이 되지않았던 개념들이 서로서로 연결이되어서 너무 이제 이해가 잘되요 ㅎㅎ 감사합니다!
크 ㅠㅠㅠ 정말 이렇게 댓글 남겨주시면 제가 너무너무 보람차고 기분이 좋습니다 ㅠㅠ
도움을 드릴 수 있어서 저도 기분이 좋으네요~!ㅎㅎ
중간고사 대박나십쇼!! 🥳🥳🥳
스레드에 대해서 이해가 잘 가지 않아서 다른 분들에게 여쭈어보다가 이 영상을 알게 되어서 보게 되었는데..
쉬운코드님 덕분에 스레드 개념을 잘 잡을 수 있게 된 것 같습니다 감사합니다!!
한 가지 궁금한 것이 있어서 질문드려봅니다!
java의 경우 One-To-One 방식으로 유저 스레드와 OS 스레드가 매핑된다고 설명해주셨습니다.
그렇다면 스레드풀로 스레드를 100개를 만들게 되면 100개의 OS 스레드가 생성되어서 매핑되는 것이고
CPU가 4코어 8스레드인 하드웨어 스레드가 있을 경우
100개의 OS 스레드들을 실행시킬 때 100개의 OS 스레드들이
8개의 하드웨어 스레드들의 자원을 사용하면서 OS 스레드들이 변경될 때 발생하는 게 컨텍스트 스위칭이라고 이해가 되는데 맞게 이해한 게 맞는지 궁금합니다!!
네 맞습니다~! 매우 아주 정확하게 설명해 주셔서 제가 덧붙일 말이 없어요!! 👍👍👍
오늘도 감사합니다 선생님. 항상 응원하겠습니다.
이제야 인사드려요ㅜㅜ 정말 감사합니다~!
궁금했던 내용이라 여기저기 알아보고 있었는데 여기서 완벽 이해하게 됬습니다!
파편화된 지식이 디스크 정리 된 기분(?) 입니다 ㅎㅎㅎ
너무 너무 도움이 된 영상이었습니다.
감사합니다!!
크 칭찬 너무 너무 감사합니다!
저도 도움을 드릴 수 있어서 뿌듯하네요 :)
자주 놀러와 주세요 좋은 영상으로 늘 인사드릴게요 👍
백엔드지식에 priority하게 순서까지 잡아주시는 쉬운코드....이건 교과서다...! 오늘도 감사히 잘보고있습니다!!
크~~!! 극찬 감사합니다!!! 맞아요 나름의 순서를 가지고 영상 업로드 중입니다ㅎㅎ 댓글 남겨주셔서 감사해요 :)
너무나도 빛과 소금 같은 영상입니다!!
감사합니다~! 앞으로도 빛과 짠 맛을 잃지 않겠숩니당~! ㅎㅎ
와 몇년 전부터 하드웨어 스레드 갯수랑 소포트웨어(?) 스레드 갯수랑 왜 차이가 나는건지 궁금했는데 이제서야 알게 되었네요
엄청나군요 대박입니다 !
크~~~! 댓글도 엄청납니다 대박이에요 !!
오늘 용량 다쓴것 같습니다 하하
하드웨어 쓰레드 = cpu
그외 쓰레드 = s/w
유저 모드에서 구현되느냐 커널모드에서 구현 되느냐에 따라 나뉘고 이 둘을 어떻게 매칭 하느냐에 따라 또 나뉘고 한두개 따로 노는 애들이 또 있음
오우 좀 쉬어야 할듯
정말 감사합니다
하드웨어 쓰레드 저거이가 늘 가상머신 구현 할때 헷갈렸는데 여기서 이해 했습니다
Amd도 비슷하겠지요?
크 여기까지 달리셨군요~!! 멋있습니다 👍
맞습니다 좀 더 오해없이 정리하자면
- 하드웨어 스레드 = CPU 레벨에서 용어
- OS 스레드 = OS 레벨에서 용어
- user 스레드 = 프로그래밍 언어 혹은 프로그래밍 언어의 virtual machine에서 용어 (가령 JVM 같은)
이렇게 될 것 같아요~
스레드 구분을 유저모드에서 구현되느냐 커널 모드에서 구현되느냐로 구분하는 것은 조금은 정확하지 않을 수 있는데요,
유저모드는 '유저가 작성한 코드'가 OS 스레드를 통해 CPU에서 바로 실행되는 모드이고,
커널모드는 유저가 작성한 코드의 요청에 의해 '커널에 존재하는 코드'가 OS 스레드를 통해 CPU에서 실행되는 모드입니다
그렇기 때문에 모드로 (스레드를 구분하기 보다는)
모드에 따라 유저 코드가 CPU에서 실행되는지 아니면 커널에 존재하는 코드가 CPU에서 실행되는지로구분하시는게 더 정확할 것 같아요 :)
참고로
커널 모드일 때도 유저 모드일 때도, OS 스레드와 유저 스레드는 모두 존재하고 있습니다
왜냐하면 (요즘은 멀티코어기 때문에) CPU의 각 코어에서 실제로 실행되는 것은 OS 스레드이고
그 OS 스레드를 개발자가 사용하기 쉽게 프로그래밍 언어 레벨로 추상화한 것이 유저 스레드이기 때문이죠
그리고 보통은 이 두 스레드가 1대 1 맵핑이지만 점점 1대 1 맵핑 외의 맵핑 형태로도 사용할 수 있도록 프로그래밍 언어들이 개발되고 발전하고 있습니다
끝으로, 맞아요 저도 AMD도 인텔과 비슷하다고 알고 있습니다 :)
@@ezcd 아하 그렇군요
모드에 따라 구분되는게 아니라 쓰레드가 os단계에서 실행이 되느냐
커널에서 실행되느냐에 따라 구분 되는거 군요
여기서 의문점이 유저모드에서 실행이 된다고 하지만 어짜피 시스템콜을 통해 커널에 요청을 하게 되면
이땐 어케 구분을 허허 아직 명확한 개념을 못잡다 보니 ㅠ
감사합니다
넵 맞습니다 :)
잘 이해하셨는데 오타를 내신 것 같지만 혹시나 하는 마음에 워딩을 정확히 하자면
>> '모드에 따라 구분되는게 아니라 쓰레드가 os단계에서 실행이 되느냐 커널에서 실행되느냐에 따라 구분 되는거 군요'
라고 써주신 이 부분을 정확히 하자면
'모드에 따라 구분되는게 아니라, CPU에서 실제로 실행되는 스레드냐 혹은 프로그래밍 언어 레벨로 추상화된 스레드냐로 구분되는 것'이 보다 더 정확한 표현일 것 같네요
참고로 OS의 핵심 기능을 담당하는 것이 커널이기 때문에 OS와 커널은 거의 유사한 개념이라고 보시면 됩니다
그리고 '실행'이라는 것의 의미는 'CPU에서' 실행을 의미하기 때문에 CPU에서 실제로 실행이 되는 것은 OS 스레드 입니다.
유저 스레드는, 이 OS 스레드를 추상화해서 프로그래밍 언어 레벨에서 개발자가 사용하기 편하게 포장된 추상화된 개념인 것이죠
그래서 '유저 스레드가 실행된다'는 표현은 엄밀히 말하면 '유저 스레드에 맵핑된 OS 스레드가 CPU에서 실행된다'라는 의미가 됩니다
이게 개념이 되게 헷갈릴 수 있습니다ㅠ
처음에 이걸 잘 이해하는게 (저도 그랬었고) 약간 난해할 수가 있어서 소화하는데 시간이 조금 필요해요
그래도 갈가마구님 항상 열정적으로 공부하시기 때문에 금방 이해하실 수 있을 것 같습니다 :)
그리고 시스템콜은 예를 들어 스레드 생성, 파일 I/O, 네트워크 I/O 같은 경우일 때 사용됩니다
그러므로 가령 아래와 같은 코드는 시스템콜과 상관 없는 부분이죠
int a = b + c;
항상 응원합니다 :)
@@ezcd 추상화 개념을 이해 못하고 있었습니다. 추상화는 어렵드라구요...한번더 봐야 겠습니다. 감사합니다.
쓰레드프로그래밍이 저런 복잡한것들이 다 자동화 최적화 되었다는거에 감동
이 어려운 용어들을 쉽게 풀어내주시다니... 너무 감사합니다!! 아 그리고 go언어 스레드 모델에 대해서 CHAT GPT형님한테 물어 봤더니 말씀하신 M:N Many to Many Model이 맞다고 하네요!!
크~! 칭찬의 말씀 정말 감사드립니다 :) 👍
오호 역시 go도 M:N 모델이 맞군요~!!
진짜 명강의입니다. 운영체제나 컴퓨터 구조 유료강의없나요?? 진짜 바로 수강하러 갑니다 ㅎㅎ
크~!! 극찬의 말씀 정말 감사합니다 ㅠㅠ
재생목록으로 운영체제와 컴퓨터구조 영상들이 정리되어 있어요~
컴퓨터구조 쪽은 영상이 거의 없지만 운영체제 쪽은 보실만한 것들이 있어서 재밌게 봐주세요 :)
항상 큰 도움이 되고 있습니다. 감사합니다.
앞으로도 좋은 영상으로 찾아뵐게요~! 감사합니다 :)
golang의 병렬처리에 사용되는 고루틴 go 키워드가 코루틴을 유저스레드로 관리하는 방식이라 빠르다고 문서에서 예전에 본 적 있습니다.
오~~! 역시 그렇군요!! 알려주셔서 감사합니다 :)
@@ezcd 좋은 영상 올려주셔서 감사합니다!
2번을 봤습니다. 한 80% 이해를 한것 같습니다.
가장 어려 이해가 힘들었던 부분은 바로 유저 스래드 부분이었습니다.
이건 프로그램언어 차원에서 추상화 한것, 추상화란 개념을 이해 못해서 생기는 문제 였습니다.
유저 스래드는 자바라는 언어 차원에서 만든 관념적인, 실체가 아닙니다. 없는건데 있다고 우기는 겁니다. (실체가 없다는 의미 입니다.)
그래서 이걸 os 스래드와 매칭하는 방법에 대한 설명이 나오는 것이구요
항상 그렇지만 제 경우는 이놈의 추상화에서 상당히 애를 먹고 있습니다.
이게 어마 어마 하게 중요하고, 유용한 개념인 것을 최근에 서야 조금씩 알아 가고 있습니다.
시간이 되신다면 추상화에 대한것만 따로 강의 한번 부탁 드려도 될지 모르겠습니다.
잘못된 정보가 넘쳐 흐르는 세상에서, 등대를 만난것 처럼 기쁩니다.
감사합니다. 응원 하겠습니다.
지칠때도 있겠지만... 힘내세요
거듭 감사합니다.
맞습니다 점점 더 정확한 의미에 다가가고 계신 것 같아요:)
나머지 20%의 이해를 돕기 위해 저도 열정적으로(^^) 조금만 더 첨언을 하자면
우선 유저 스레드를 '실체가 없다' 는 표현은 듣기에 따라서는 반론이 나올 수도 있습니다
왜냐하면 가령 자바의 스레드나 파이썬의 스레드나 모두 각 언어에서 클래스의 형태로 개발자에게 제공하고 있고,
그래서 개발자가 실제로 사용하기 때문에 실체가 없다고 한다면 약간의 논란이 있을 수 있을 것 같아요
그렇지만 '실체가 없다'라는 표현이 한편으로는 맞는 표현인데요, 왜냐하면
CPU의 입장에서는 유저 스레드는 존재하지 않기 때문입니다
왜냐하면 CPU에서 실제로 실행되는 것은 항상 OS 스레드이기 때문에 CPU 입장에서는 유저 스레드의 존재 자체를 알 수가 없는 거죠
하지만 개발자는 개발하면서 OS 스레드를 다이렉트로 사용하기 보다는 프로그래밍 언어가 한번 포장하여 (혹은 재정의하여) 제공한 유저 스레드를 통해 OS 스레드를 사용하기 때문에, 유저 스레드가 개발자에게는 실체가 있는 존재여서, '실체가 없다'는 표현은 어떤 입장에서 보느냐에 따라 맞기도 하고 틀리기도 할 것 같아요
그리고 유저 스레드 개념은 자바에 국한된 개념은 아니고, 프로그래밍 언어 세계에서 일반화된 개념입니다
유저 스레드와 OS 스레드가 1대 1 맵핑일 때는 어차피 1대 1 맵핑이라 둘 다 퉁쳐서 스레드라고 주로 부르지만,
그 외의 경우에는 언어에 따라 코루틴, 고루틴 등등 다양한 용어로 불리게 됩니다
추상화와 관련된 영상은 기회가 되면 준비해볼게용 👍
끝까지 파고 들어가시는 모습 정말 멋있습니다!! 최고십니다!!
@@ezcd보이는데 보이지 않는
관점에 따라 있기도 하고 없기도 한
프로그램 이란걸 공부 하면서 점점 더 드는 생각이 왜 자꾸 철학적인 관점으로 연결 되는듯한 느낌입니다....극과 극은 통한다는 건지... 어디 프로그램으로 어디까지 갈 수 있을지...재밌을거 같습니다.
감사합니다
@@갈가마구 오 맞습니다 개발에도 철학이라는 것이 존재하죠 :)
점점 더 재밌어질 거에요👍
@쉬운코드
언어에따라 유저레벨쓰레드를 서브루틴이라 부르기도한다 라고하셨는데요
아래글을 읽을때는 좀 다르다고 느껴집니다
관련해서 도움을 주실수 있을까요?
참고할만한 reference만 던져주셔도 감사드리겠습니다!
stackoverflow.com/questions/20169633/what-is-the-difference-between-user-level-threads-and-coroutines
@Seunghyun Yoo 안녕하세요~! 우선 영상을 시청해 주셔서 정말 감사드립니다 :)
정확한 답변을 드리고 싶어서요,
혹시 어떻게 다르게 느껴지셨는지 알려주실 수 있을까요?
그러면 제가 더 잘 정리해서 말씀드릴 수 있을 것 같아요 👍
강의 너무 감사드립니다! 지금은 현업으로 돌아가셨지만 너무너무 잘 들었습니다.
질문이 하나 생겨서요!
유저 스레드의 컨텍스트 스위칭이 더 빠르다는 의미를 잘 이해하지 못 하겠습니다. 음 어찌되었든 컨택스트 스위칭이 일어나게 된다면 cpu의 캐시나 페이지 테이블이 변경되어야 하는데 같은 프로세스 내 스레드들만 묶어주게 되면 이런 것들이 발생하지 않으니 비용이 싸다는 의미인가? 로 이해했습니다.
혹시 비슷한 질문과 답변이 있지 않을까해서 덧글을 모두 읽어보니
'''
그건 프로그래밍 언어가 어떻게 구현했는지에 따라 여러 방식이 있는데요,
가령 개발자가 직접 스위칭할 위치를 지정해 줄 수 있습니다. 그러니까 코드로 유저 레벨 스레드가 스위칭 해야할 위치를 명시할 수 있습니다.
예를 들어 피이썬의 코루틴이 이와 같은 방식으로 동작합니다.
파이썬의 코루틴은 유저레벨스레드이구요, async/await 문법을 통해 실행 중인 코루틴이 어느 위치에서 다른 코루틴으로 스위칭해야하는지 기술할 수 있죠
'''
이렇게 답변하신 것이 있더라고요. 파이썬의 경우를 생각해보면 제가 생각한 것이 맞는 것 같은데 그럼 보통 many to one 모델은 하나의 프로세스에서 여러 스레드들을 사용하는 경우 사용한다라고 생각해도 될까요?
명강의입니다!! 최고
이번 영상 보고 후원 시작했습니다. 감사합니다!
우오 ㅠㅠㅠ 정말 감사합니다!! 큰 힘이 됩니다!!! 👍
앞으로도 꾸준히 유익한 영상 올릴게요~! 다시 한번 감사합니다!! 최최고!! 👍
정말 최고의 강의입니다. 👍
흐엉 ㅠㅠ 극찬 정말로 감사드립니다!!! ㅠㅠ
와 대박 너무 잘 봤습니다 ㅎㅎㅎㅎ
명재님은 사랑입니다 ❤
좋은 영상 감사합니다 ㅎㅎ 혹시 코루틴 관련된 영상은 언제쯤 업로드될까요? 완전 기대하고있습니다 ㅎㅎ!!
귀한 댓글 감사합니다~!ㅎ
코루틴은 조금 뒤로 밀렸어요 ㅠ 컴공 관련 지식부터 먼저 마무리를 하고, 이후에 백엔드 관련해서 직접적으로 다루기 시작할 때 다루게 될 것 같아요
그래서.. 아마도 몇 개월 뒤가 될 것 같아요..ㅠㅠ (올해 안에는 합니다 ㅎㅎ)
여러 프로세스를 메모리에 올려두고 io가 있을 때 다른 프로세스가 cpu를 점유하는 멀티 프로그래밍 기법과 하드웨어 하이퍼 스레딩이 유사해보이는데 맞나요..?
OS가 소프트웨어적으로 하드웨어에서 제공하는 하이퍼 스레드를 지원하는 게 멀티 프로그래밍 기법으로 이해하는 게 맞을지 궁금합니다..!
와 좋은 설명 감사합니다
우와 저도 댓글 감사해요 :)
좋은 강의 너무나 감사합니다!!
하드웨어 스레드와 os 스레드를 연결 지어서 생각해 보는데 뭔가 찜찜한게 남아 있어서 질문 드립니다!!
자바같은 경우 1 대 1로 os 스레드가 생성된다고 하는데 그럼 여기서 하드웨어 스레드 보다 더 많은 스레드가 생성된다면 영상에 나온 예처럼
이 스레드들은 동시에 실행이 안 되고 cpu할당 받기를 기다리는거죠? cpu스케줄링을 통해서??
네 그렇습니다~! 완전 정확하게 말씀해주셔서 제가 더 드릴 말씀이 없네요 ㅎㅎ 👍
영상 잘 보았습니다!, 한가지 궁금한점이 있습니다. one-to-many 모델을 사용할때 결국은 하나의 os thread에서 여러개의 user thread를 실행하는 것이기 때문에 동시에 실행될수가 없어서 절대로 race condition이 발생하지 않게 되는 것이 맞나요?
안녕하세요~!! 유익하게 봐주셔서 감사합니다 :)
many-to-one 질문이신거죠? 답변 드리면 '절대로'는 아닐 수 있을 것 같고요, 왜냐하면 유저 스레드들이 어쨌든 유저 레벨에서 스케줄링 될 거라서 해당 모델을 어떻게 구현하는지에 따라서는 race condition이 발생할 가능성도 있을 것 같습니다~
하지만 어쨌든 다른 모델들에 비해서는 발생할 여지가 상당히 적겠죠
이 부분에 대한 설명은 영상의 15:55에서도 간략하게 언급했으니 참고 부탁드려요 :)
안녕하세요. 높은 퀄리티의 내용을 쉽게 쉽게 전달해주셔서 진심으로 감사드려요. 정말 큰 도움이 되고 있습니다. :)
영상 내용 중에 궁금한 점이 있는데요. Java Thread model 관련해서 초기에 Java는 Many-to-One(Green thread) Model을 사용하다 Many-to-Many Model을 사용하는 것으로 알고 있었습니다. 즉, User Thread들의 스케줄링을 JVM이 해주는 것으로 알고 있었는데요. (Oracle reference를 통해 습득한 내용입니다.) 영상 내용을 보니 현재 Java가 사용 중인 모델이 One-to-One 모델이라고 하셔서요. 혹시 이 내용의 출처를 알 수 있을까요?? 자료를 찾아보니 그럴 수도 있겠다 싶은 내용은 있지만, 명확한 자료가 없어서 문의 드려요 ㅠ.ㅠ
반갑습니다 :) 영상을 좋게 평가해 주시고 유익하게 봐주셔서 정말 감사드려요 👍
질문주신 내용에 답변 드리겠습니당
우선 java가 many-to-many 모델이라고 말씀하신 부분의 오라클 레퍼런스가 아래 링크 비슷한 내용인가요?
docs.oracle.com/cd/E19620-01/805-4031/6j3qv1oej/index.html
이런 종류의 글을 말씀하시는 거라면 이건 Solaris OS 한정으로 봐야할 것 같아요
기본적으로 자바는 threading model을 직접 JVM에서 관리하는 것이 아니라 그 아래 단의 OS에 위임을 합니다.
이건 소스코드를 보면 알 수 있는데요,
jdk의 Thread 클래스의 소스코드를 보시면 start 메서드에서 start0메서드를 호출하는데요,, (아래 링크 691번 라인 참고)
github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/lang/Thread.java#L691
이 start0는 private native void start0(); 로 되어 있습니다 (705번 라인)
여기서 native 키워드는 C나 C++ 처럼 다른 언어로 구현된 것을 호출하기 위해 사용되는 키워드이며, JVM은 이 키워드를 보고 JNI(Java native interface)를 통해 아래단의 OS 플랫폼에서 제공하는 라이브러리 메서드를 호출합니다
그렇기 때문에 OS 플랫폼에서 어떻게 라이브러리를 제공하는지 따라 one-to-one일 수도 있고 many-to-many일 수도 있습니다.
위 링크에서 Solaris OS의 경우에는 제공하는 라이브러리가 many-to-many로 동작하도록 구현됐기 때문에 many-to-many인 거고요,
하지만 우리가 가장 흔히 사용하는 윈도우나 리눅스 같은 경우에는 플랫폼 레벨에서 one-to-one model 방식으로 동작하도록 라이브러리를 제공합니다
구글링을 이미 해보셨지만 도움 되실 수 있게 몇 가지 링크를 걸어둘게요 👍
* 윈도우와 리눅스에서 java thread와 OS thread(혹은 kernel thread)는 one-to-one이라고 설명하는 글 : www.developer.com/design/an-introduction-to-jvm-threading-implementation/
* 비슷한 종류의 질문들에 대한 답변들
- stackoverflow.com/questions/17125101/one-to-one-mapping-of-java-thread-to-linux-thread-lwp
- www.quora.com/Are-Java-threads-user-level-threads/answer/Robert-Love-1?ch=10&oid=2065330&share=39208bda&target_type=answer
(참고로 이런 종류의 내용은 공식 문서에서 찾기 쉽지 않더라고요 ㅠ)
최근 영상이 아니고 여러모로 바쁘실거라 생각해서 문의 시 망설임이 많았었는데 ㅠ.ㅠ 빠르고 상세한 답변 진심으로 감사합니다. 👍👍
Oracle 레퍼런스는 위 자료가 맞습니다. Solalis OS에 대한 내용이였는데, Windows/linux에 대한 내용이 따로 없고 또 다른 자료들에서 Java의 기본 방식인 것처럼 설명을 하고 있어서 제가 잘못 이해를 한 거 같아요.
공식 문서를 통해 확실히 알고 싶었는데, 말씀대로 그런 내용을 찾기가 쉽지 않더라구요ㅠ.ㅠ
공유주신 자료가 매우 도움이 되었습니다~👍
혹시 몰라 JNI와 JVM의 소스 코드를 직접 확인해보니 OS 별로 분리 구현되어 있었고, 말씀대로 윈도우와 리눅스의 대해서 one-to-one 방식으로 동작하도록 구현이 되어 있었네요. 속이 시원합니다 :)
hg.openjdk.java.net/jdk9/jdk9/jdk/file/00cd9dc3c2b5/src/share/native/java/lang/Thread.c
hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/prims/jvm.cpp
hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/runtime/thread.cpp
hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/runtime/osThread.cpp
hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/os/linux/vm/osThread_linux.cpp
운영체제 영상들을 몇 번씩 봤는지 잘 모를 정도로 여러번 보고 있는데, 개인적으로 정말 유익하고 많은 깨달음을 얻고 있습니다.
진심으로 감사드려요. 주변에도 널리 알릴게요 ㅎㅎ
그럼 수고하세요~!
@@beansroa2755 와 멋지십니다~!
처음 써주신 질문에서도 저를 배려해 주시는 마음이 느껴졌었는데, 두 번째 댓글도 이렇게 젠틀하고 나이스하게 써주셔서 기분이 참 좋으네요 👍
그리고 이렇게 꼼꼼하게 확인하시는 모습에 저도 좋은 자극을 받게 됐습니다 :)
영상들을 자주 봐주셔서 정말 감사해요!! 훌륭하신 개발자분들이 많이 나오길 바라는 마음에서, 그리고 컴공 공부하시는 분들이 조금이라도 더 편하게 공부하실수 있길 바라는 마음에서 영상을 열심히 만들고 있는데요, 이렇게 댓글 써주시면 정말 큰 힘이 되고, 다시 한번 달려가는 추진력을 얻게 되는 것 같습니다 👍👍👍
댓글 정말 감사합니다! 앞으로도 꾸준히 파이팅 할게요 !!
이 댓글과 대댓글보고 명쾌하게 답을 얻었습니다!
영상 너무 재미있습니다.
그렇다면 찐개발자십니다 👍 ㅎㅎ
선생님 정말 좋은 강의로 가르쳐주셔서 감사합니다
궁금한 점이 생겨서 질문을 받아주시면 감사하겠습니다
저는 여태까지
유저레벨 소스코드는 유저레벨 스레드가 실행시켜주는 것이고
중간에 시스템콜을 호출하면, 커널의 코드는 커널레벨 스레드가 실행시켜 주는 것이라고 이해하고 있었습니다
예를 들면
#include
int b( )
{
return 5;
}
int main()
{
int a=b( ); // 이 부분은 유저레벨 스레드가 실행
시스템콜( ); // 이 부분은 커널레벨 스레드가 실행
}
으로 알고 있었습니다
그런데, 강의 7분 20초에서
커널레벨 스레드가 사용자 코드와 커널 코드 모두 개입한다고 말씀해주셔서요
그러면
int a=b( );
이 코드도 유저레벨 스레드가 아닌 커널 레벨 스레드가 개입하는건지 궁금해서 여쭙고 싶습니다
질문 읽어주셔서 감사합니다
그리고 좋은 강의를 올려주셔서 정말 감사드립니다
안녕하세요~ 먼저 영상에 대해 좋게 봐주셔서 감사합니다 :) 선생님이라뇨ㅠㅠ 몸둘 바를 모르겠습니당 ㅎㅎ
질문 주신 것에 답을 두괄식으로 드리면 말씀하신 것처럼 int a = b(); 이 코드도 결국 커널 레벨 스레드에 의해 실행된다고 보시는 것이 맞습니다.
조금 더 자세히 설명을 드리면,
'CPU에서 실행'이라는 관점에서 생각해보면 좀 더 쉽게 이해하실 수 있는데요,
CPU와 프로그램의 인터페이스 역할을 하는 것이 OS이고 CPU 등의 하드웨어 입장에서는 운영체제만 바라보기 때문에
OS 스레드(혹은 커널레벨 스레드)가 있어야만 CPU에서 실행될 수 있습니다.
즉, 개발자가 작성한 프로그램이 CPU에서 실행된다는 것은 개발자가 작성한 코드들은 OS 스레드에 담기게 되고,
CPU에서는 OS 스레드에 담긴 개발자가 작성한 유저 레벨 '코드'나 혹은 시스템 콜 같은 커널 레벨 '코드'가 실행된다는 의미이기 때문에
CPU에서 코드가 실행되기 위해서는 OS 스레드가 반드시 필요합니다.
그럼 유저 레벨 스레드라는 것은 무엇이냐면,
프로그래밍 언어 레벨에서 정의하거나 혹은 추상화한 스레드라고 생각하시면 이해하시는데 도움이 될 것 같습니다.
예를 들어 자바나 파이썬(CPython) 같은 경우를 보면 각각 스레드라는 클래스가 있는데요,
이를 바탕으로 스레드를 하나씩 만들 때마다 OS 스레드도 하나씩 만들어지는 1대 1 맵핑 관계입니다.
자바나 파이썬 언어를 설계하고 만든 사람들의 철학이, 그들의 세계관에서는 자신들의 스레드를 OS 스레드와 1대 1로 연결시키기로 정의한 거죠.
즉, 이들 언어의 스레드 정책은, 그 언어에서 스레드를 사용한다는 것은 곧 OS 스레드를 사용한다는 것으로 만들어버린 것입니다.
아마 대부분의 프로그래밍 언어에서 스레드라고 하면 OS 스레드와 1대1로 맵핑되는 구조일 것 같구요,
영상에서 설명했던 것처럼 1대1 맵핑 말고도 다대일 맵핑, 다대다 맵핑 등등 여러 형태의 맵핑 방식이 있는데,
이런 경우에 유저 레벨 스레드는 스레드라고 부르기 보다는 각각 독립적인 네이밍(가령, 그린스레드, 코루틴 혹은 고루틴 등등)을 쓰는 것 같아요.
어쨌든 핵심은 유저 레벨의 스레드는 각 프로그래밍 언어의 철학에 따라 프로그래밍 언어 레벨에서 추상화된 스레드이며
이들 스레드가 실제로 CPU에서 실행되기 위해서는
CPU는 OS를 통해서만 소통(?)하기 때문에 반드시 OS 스레드와 연결되어야 한다는 점,
그래서 실제로 CPU에서 실행될 때는 OS 스레드에 의해 실행된다고 이해하시면 될 것 같아요~
@쉬운코드 선생님 정말 상세한 가르침을 주셔서 고맙습니다
제가 혹시 제대로 이해했는지 봐주시면 정말 감사하겠습니다
1. 시스템콜의 코드는 커널레벨 스레드가 실행시킵니다.
커널모드에서 동작하는 스레드이기 때문입니다
2. 유저레벨의 코드를 실행시킨다는 것은 유저모드에서 동작하는 것을 의미합니다
그러나, 유저모드에서는 유저레벨의 스레드만 동작하지 않습니다
유저레벨의 코드가 실행되려면 , 유저레벨스레드와 커널레벨스레드 모두 필요합니다
그 이유는,
유저레벨의 코드 예를 들면, int a = b(); 또는 라이브러리 함수들은
유저레벨 스레드가 실행시키긴 하지만,
실제로 프로세스가 실행되려면 CPU를 점유해야 하는데
실제로 CPU를 점유하는 스레드는 커널 레벨 스레드이기 때문입니다.
따라서, 유저레벨의 소스코드를 실행시킬 경우에는
유저레벨스레드와 커널레벨스레드가 같이 작동합니다
3. 다 대 일 모델의 문제가
여기서 이어집니다
다 대 일 모델에서는
유저레벨스레드가 5개여도,
결국, 유저레벨스레드 1개가 실제로 실행이 되려면
CPU를 점유하고 있는 커널레벨스레드 1개와 연결이 되어야 합니다
유저레벨 스레드 5개 중 1개가 커널레벨스레드를 점유하고 있으면
나머지 4개 유저레벨 스레드들은 놀고 있습니다
4. 같은 원리로
다 대 일 모델에서는
커널 레벨 스레드 하나가 blocking 되면, 유저레벨스레드들도 중단하게 됩니다
라고 이해했는데, 혹시 번거로우시겠지만, 이렇게 이해해도 되는지 봐주시면 감사하겠습니다
좋은 강의 들려주시고, 정말 상세하게 가르쳐주셔서 감사합니다 ㅠㅠ
@@light8013 오~! 거의 비슷합니다~! 조금만 더 정확하게 설명을 드려볼게요. :)
우선 용어 정리부터 다시 명확히 하자면,
커널 레벨 스레드(=OS 스레드)는 커널에서 관리하는 스레드, 즉,CPU 스케줄링의 대상이 되는 스레드, 실제로 CPU에서 실행되는 스레드이며
유저 레벨 스레드는 개발자가 프로그래밍 언어로 부터 제공받는, 각 프로그래밍 언어 세계관에서 존재하는 '관념적인' 스레드라고 이해를 하시면 되겠습니다
즉, 유저 레벨 스레드는 프로그래밍 언어 레벨에서 언어의 철학에 맞게 '추상화한 개념'이라고 이해하시는게 제일 정확한 것 같습니다.
스레드를 프로그래밍 언어 관점에서 보느냐, 아니면 OS나 CPU의 관점에서 보느냐에 따라 유저 레벨 스레드로 보느냐, 커널 레벨 스레드로 보느냐로 나눠지는 부분이라서
유저 레벨 스레드와 커널 레벨 스레드를 대등한 위치에 놓고 비교하기에는 조금 어려움이 있습니다.
예를 들어, 자바로 코드를 작성해서 실행해보면, 개발자가 작성한 자바 코드는 (개발자가 명시적으로 자바 스레드를 만들지 않았어도) 하나의 자바 스레드 위에서 실행이 됩니다. 여기서 이 자바 스레드는 자바 언어가 정의한 자바의 '유저 레벨 스레드'입니다. 그리고 자바는, 언어 정책 상, 자바 스레드와 OS 스레드를 1대1로 맵핑시켜서 사용합니다. 결국 개발자가 작성한 자바 코드는 자바 스레드에서 실행되지만 최종적으로 OS 스레드에 의해 CPU에서 실행이 될 겁니다.
그러면 이 때 사용자가 작성한 코드는 자바 스레드(= 자바의 유저 레벨 스레드)에 의해서 실행되는 것일까요? 아니면 OS 스레드(=커널 레벨 스레드)에 의해 실행되는 것일까요?
이 질문을 유저 레벨 스레드와 OS 스레드를 같은 위치에서 동등하게 놓고 이해하려면 헷갈릴 수 있는데요, 이 문제는 스레드를 어떻게 바라보느냐라는 관점의 문제이기 때문입니다.
프로그래밍 언어 혹은 그 언어를 사용하는 개발자 관점에서 보면 해당 코드는 자바 스레드(=유저 레벨 스레드)에서 실행된다고 볼 수 있습니다.
반면에 OS 관점에서 혹은 CPU 관점에서 보면 해당 코드는 OS 스레드에서 실행된다고 볼 수 있습니다.
이런 맥락에서 질문주신 내용에 답변을 드리자면
1.커널 레벨 스레드(OS 스레드)가 실제로 CPU에서 실행되는 스레드이기 때문에 시스템콜의 코드는 커널 레벨 스레드에서 실행이 됩니다.
그리고 (아마 이해하시고 계시겠지만) 커널 레벨 스레드는 커널 모드에서만 동작하는 스레드는 아닙니다. 스레드의 생성과 실행/관리를 커널이 주관한다는 의미에서 커널 레벨 스레드라고 부르는 것이지, 커널 모드에서만 실행한다는 의미는 아닙니다. 유저 모드에서 실행되는 유저 레벨의 코드들도 (CPU 관점에서 보면) 커널 레벨 스레드에서 실행됩니다. 여담이지만 저는 개인적으로 커널 레벨 스레드라는 용어보다는 OS 스레드라는 용어가 좀 더 좋다고 생각하는데요, 커널 레벨 스레드라고 하면 마치 커널 모드에서만 실행될 것 같은 느낌을 주기도 하고, 비슷한 이름이지만 다른 의미를 가지는 커널 스레드라는 용어가 존재하기 때문입니다.
2. 유저 레벨 스레드와 커널 레벨 스레드는 관점의 차이에서 비롯된 개념이라는 것만 잘 이해하셨다면 말씀하신 내용이 맞습니다. 유저 레벨 스레드는 개발자에게 제공되는 추상화된 혹은 관념적인 개념임을 잘 이해해주시는게 핵심일 듯 싶네요.
3. 맞습니다 :) 물론 여기서 논다는 개념은 CPU를 사용하지 못한다는 개념일거구요~
4. 역시 맞습니다. 첨언을 드리자면, 커널 레벨 스레드가 블락이 된 이유는 유저 레벨 스레드 중에 하나에 블락킹 코드가 있었고 그 코드가 커널 레벨 스레드에서 실행되다가 커널 레벨 스레드가 블락됐을 거라고 짐작해볼 수 있죠.
제가 육아를 하러 가야해서 혹시 여전히 헷갈리시면 댓글 남겨주시면 늦은 밤에 답변 드릴게요 :)
@쉬운코드 선생님 이렇게 자세하고 상세하게 가르쳐주셔서 감사합니다
정말 너무 고맙습니다(꾸벅)
선생님 덕분에 궁금했던 부분들이 거의 다 이해가 되는 것 같습니다 ㅠㅠ
사용자 레벨 쓰레드가 추상적이고 관념적인 개념이라는 말씀에서
추상적이고, 관념적인 것에 대해 생각하다가
제가 바보라서 혹시 이렇게 이해해도 되는지 여쭙고 싶습니다
1. 다 대 일 관계를 보면
아무리 사용자 레벨 쓰레드들이 많아도
cpu 입장에서는 싱글코어에 os 쓰레드 하나만 연결되어 있으니
cpu 입장에서도 싱글 쓰레드로 보이고
실제로 일을 하는 것은 싱글 쓰레드입니다
2. 사용자 영역의 프로세스에 아무리 많은 쓰레드들이 있어도
커널 입장에서는 os의 싱글 쓰레드에 연결된 사용자 프로세스 하나가 있을 뿐입니다.
3. 개발자가 유저 레벨 라이브러리로, 유저 레벨 쓰레드를 멀티 쓰레드로 구현하면
이 유저레벨쓰레드들은 cpu를 점유하기 위해 경쟁할 것입니다
4.
그러나, 실제로는 cpu와 연결된 os 쓰레드가 코드를 실행시키기에
(사용자 레벨 코드든, 커널의 코드든 os 쓰레드가 실행시킵니다.)
5. 결국, 사용자 레벨 쓰레드들이 cpu를 점유하기 위해 경쟁한다는 것은
cpu를 실제로 점유한 os 쓰레드와 연결되기 위해 경쟁한다는 것입니다
6. 결국 다 대 일 모델은
cpu나 커널의 관점에서는 싱글 코어와 싱글 쓰레드가 일을 하는 것입니다
7. 사용자 레벨 쓰레드들 중 하나가
cpu를 점유해서 자신의 코드를 실행했다는 의미는
.
실제로는 cpu를 점유하고, 실제로 일하는 os 쓰레드가
해당 사용자 레벨 쓰레드가 실행하기로 약속한 실행코드를
os 쓰레드가 대신 실행해주었다는 것입니다
라고 이해했습니다 선생님
선생님 정말 고맙습니다
@@light8013 어유 바보라니요 열심히 하시는 모습 멋지십니다~!
유저 레벨 스레드가 추상화 혹은 관념적 개념이라는 의미는 이렇게 이해하시면 어떨까요?
예를 들어 리눅스라는 OS는 C언어 기반으로 짜여져 있습니다. 이제 이 리눅스 위에서 동작하는 프로그램을 개발하려면 우리는 프로그래밍 언어 하나를 골라서 개발을 하게 되는데, 예를 들어 자바라고 해보겠습니다. 자바로 개발을 하다가 스레드를 사용하고 싶어졌습니다. 그럼 개발자는 자바가 제공하는 자바 스레드를 사용하여 개발할 수 있습니다.
이제 이 프로그램을 리눅스에서 실행하면 잘 동작하는 것을 확인할 수 있습니다. 잘 동작한다는 것은 결국 CPU 관점에서 생각해보면서 리눅스의 OS 스레드에서 코드가 실행됐다는 것인데, 여기서 재밌는 점은 자바에서 제공하는 자바 스레드로 개발했을 뿐임에도, 어떻게 리눅스의 OS 스레드가 실행되냐라는 점입니다.
오직 자바로만 개발했고, C언어로는 개발하지 않았음에도 어떻게 C언어로 개발된 리눅스 OS 스레드를 사용할 수 있게 된 것일까요?
그것은 자바라는 언어가 OS 스레드를 추상화하여 자바 스레드라는 형태로 개발자에게 제공을 했기 때문입니다. 여기서 자바 스레드는 유저 레벨 스레드이지만 자바라는 언어의 스레드 정책은 자바 스레드와 OS 스레드를 1대 1 맵핑 시키기 때문에 결국 OS 스레드를 사용하는 것과 똑같아 지는 것이죠.
반면 자바의 아주 초창기 모델은 이런저런 이유들로 (그린스레드라고 해서) 자바 스레드를 여러개 만들어도 OS 스레드 하나와 맵핑되는 다대일 구조였습니다. 즉, 초창기 자바 버전에서는, 자바 개발자가 자바 스레드를 여러개 만들어 개발을 해도 실제로 OS 레벨에서는 하나의 스레드에 맵핑이 됐기 때문에, 여러 자바 스레드가 하나의 OS 스레드를 두고 서로 번갈아가며 실행되는 형태였었죠.
이제 이런 맥락에서 질문주신 내용을 좀 더 매끄럽게 정리해보겠습니다.
1. 다 대 일 관계를 보면
아무리 사용자 레벨 쓰레드들이 많아도
cpu 입장에서는 (싱글코어인지 멀티코어인지는 중요하진 않습니다) os 스레드 하나와 연결되기 때문에
cpu 입장에서는 싱글 OS 쓰레드로 보이고
실제로 CPU에서 실행되는 것은 싱글 OS 쓰레드입니다
2. 요건 정확히 어떤 것을 의도한 질문인지 잘 모르겠습니다ㅠㅠ.
스레드와 프로세스에 관한 질문인가요? 요건 또 다른 주제라 일단 패스할게요
3~5. (한번에 쓸게요)
다 대 일 관계에서는
개발자가 유저 레벨 쓰레드를 여러개 만들면
이 유저레벨쓰레드들이 cpu를 점유하기 위해 경쟁하는 것처럼 생각할 수도 있지만
그러나 엄밀히 말하면 실제로 cpu에서 실행되는 것은 os 쓰레드이기 때문에
(OS 스레드가 코드를 실행'시킨다'는 것은 약간 저는 어색합니다. OS 스레드에 코드가 포함되어 있고 그 OS 스레드가 스케줄러에 의해 선택되어 디스패처에 의해 CPU에 디스패치되면 그 코드들이 실행이 되는 거라서 시킨다는 느낌은 저는 조금 어색하더라구요 ㅠ)
결국, 사용자 레벨 쓰레드들이 cpu를 점유하기 위해 경쟁한다는 것은
cpu에서 실제로 실행되는 os 쓰레드와 연결되기 위해(혹은 os 쓰레드를 점유하기 위해) 스케줄링(제 개인적으로는 경쟁보다는 스케줄링이라는 표현이 더 적절할 것 같아요) 되는 것을 의미합니다.
6. 결국 다 대 일 모델은
cpu나 커널의 관점에서는 (코어 갯수는 상관없는 부분입니다) 싱글 OS 쓰레드가 실행되는 것입니다.
7. 다 대 일 모델에서는
사용자 레벨 쓰레드들 중 하나가
cpu를 점유해서 자신의 코드를 실행했다는 의미는
실제로는 cpu에서 실행되는 os 쓰레드가
해당 사용자 레벨 쓰레드가 담당하는 실행코드를
(대신) 실행했다는 의미가 됩니다
참고로 일반적으로 '스레드'라고 하면 OS 스레드, 혹은 OS 스레드와 1대 1로 맵핑되는 유저 레벨 스레드라고 생각하시면 될 것 같습니다. (물론 언어에 따라 잘 파악해야겠지만 저는 지금까지 이렇게 이해해도 어려움이 없었습니다)
다대일 모델이거나 다대다 모델일 때는 유저 레벨의 스레드를 지칭하는 별도의 네이밍을 언어마다 정해서 쓰더라구요.
안녕하세요 선생님 꿀같은 강의 감사합니다 ㅎㅎ
궁금한 점이 있는데요
1. OS 스레드는 OS가 스케줄링하여 CPU를 할당하는 게 맞을까요?
2. 그럼 다대다 혹은 다대일처럼 여러 개의 유저 스레드가 OS 스레드에 할당되어야 하는 경우에는 유저 스레드 - OS 스레드 간에 스케줄링은 누가 담당하나요?
혹시 영상에 이미 나온 내용이라면 죄송합니다 ㅠㅠ
아이쿠 선생님이라뇨 과찬이십니다 ㅠㅠ ㅎ
그저 같은 길을 걸어가는 같이 성장하고픈 개발자로 봐주세요 ㅎㅎ
1. 네 맞습니다!!
2. 저는 유저 스레드의 개념을 넓게 보는데요, 그렇기 때문에 유저 스레드를 누가 스케줄링 하느냐 했을 때 크게 두 가지로 답변할 수 있을 것 같습니다
첫째는, 언어가 제공하는 virtual machine이 담당합니다
대표적인 예가 아주 초창기 자바 버전에서는 green thread가 있었는데 예가 유저 스레드입니다
그리고 이 친구들의 스케줄링을 담당하는 것은 java virtual machine이고요
둘째는, 개발자가 직접 프로그래밍 언어를 통해 언제 컨텍스트 스위칭이 일어나는지 명시하는 방법입니다
프로그래밍 언어는 스위칭할 타이밍을 지정할 수있게 문법을 제공하고 개발자는 그 문법을 활용해서 스위칭 할 위치를 명시하는 형태인데요, 오늘날 이 형태가 메인 패러다임이 되고 있습니다
즉, 스케줄링 위치를 개발자가 직접 언어가 제공하는 문법으로 챙기는 거죠
코루틴이 이렇게 동작합니다
무릎을 탁 치고 갑니다!!! 이렇게 친절하고 명쾌하게 설명해주는 곳은 어디에도 없었어요 ㅠㅠ 저한테는 선생님이셔요 👍구독도 눌렀어요 ㅎㅎ 멋진 지식 나눠주셔서 감사합니다~!
@@jiwon3373 아이쿠 좋게 봐주셔서 너무 감사합니다 👍구독도 정말 감사하고요 ㅠㅠ👍👍👍
앞으로도 자주 놀러와 주세요
저도 꾸준히 좋은 영상 준비해 놓고 있을게요 선생님 :)
(저만 선생님 듣는게 쑥쓰러워서 서로 부르는 걸로 해요 ㅎㅎ)
커널(OS)스레드는 CPU인터럽트에의해 스위칭되는데, 유저레벨스레드는 어떻게 다른유저레벨스레드로 스위칭될 수 있을까요?
그건 프로그래밍 언어가 어떻게 구현했는지에 따라 여러 방식이 있는데요,
가령 개발자가 직접 스위칭할 위치를 지정해 줄 수 있습니다. 그러니까 코드로 유저 레벨 스레드가 스위칭 해야할 위치를 명시할 수 있습니다.
예를 들어 피이썬의 코루틴이 이와 같은 방식으로 동작합니다.
파이썬의 코루틴은 유저레벨스레드이구요, async/await 문법을 통해 실행 중인 코루틴이 어느 위치에서 다른 코루틴으로 스위칭해야하는지 기술할 수 있죠
user space 코드를 실행하는 스레드와 실행하다가 인터럽트 또는 시스템콜이 발생했을때 kernel 코드를 실행하는 스레드는 모두 os 스레드로 동일한건 이해했는데요 user space 코드와 kernel space 코드를 실행하는 스레드는 다른 스레드인가요? (즉, 인터럽트 또는 시스템 콜 발생시 똑같은 스레드에서 실행되는게 아니라 스위칭이 일어나는지)
똑같은 os 스레드입니다~~
하나의 os 스레드가 user space에 있는 코드를 실행하다가 인터럽트나 시스템콜을 만나면 kernel sapce 코드로 점프해서 이어서 실행하게 됩니다
강의 잘 봤습니다~
항상 강의를 들으면서 느끼지만 개념마다 적절한 예시를 들면서 설명해주셔서 이해하기 쉽네요.
오늘도 질문이 생겨서 댓글 남깁니다!
강의 내용을 실제 프로그램이 실행되어 프로세스 상태일때 어떻게 적용시킬 수 있을까 고민하다보니 아래와 같은 궁금점이 생겼습니다.
프로그램이 실제로 실행되어 프로세스가 되면, 프로세스마다 각자 가상메모리를 갖게되는 것으로 알고 있습니다.
프로세스의 가상메모리 안에는 프로세스가 실행되기 위한 여러 정보들이 저장되어있을 것이고, 크게 4가지로 분류하여 코드, 데이터, 스택, 힙이 있다고 알고 있는데, 가상메모리 안에는 저 4개의 영역을 제외하고, 커널을 위해
예약된(reserved) 영역이 있다고 알고 있습니다.
1. 그렇다면, 한 프로그램 내에서 만약에 유저모드에서 일반적인 코드를 실행할때는 os 스레드가 가상메모리의 코드 영역에서 명령어를 fetch 해와서 cpu에서 실행하는 것이고, 만약 시스템콜이나 io같은 커널레벨의 코드를 실행해야하는 경우에는 위에서 언급한 커널을 위해 예약된 영역에 해당 시스템콜이나 io를 위한 코드가 저장되어 있기 때문에, 그 부분에 os 스레드가 접근하여 cpu로 실행하는 것인가요?
2. 강의의 맨 마지막의 kernel thread를 cpu에서의 연산을 위해 사용되는 os 스레드와 혼동하지 않기 위해 'os커널의 역할을 수행하는 스레드' 라고 설명해주셨는데, 구체적으로 os커널의 어떤 역할을 수행하는 것인가요?
실제 os 커널이 수행하는 스케쥴링, 자원관리, 감시 등과 같은 것들을 말하는 것인지, 아니면 질문 1번에서 유저프로그램이 시스템콜이나 io같은 커널레벨의 코드를 실행해야하는 경우에 이를 수행해주는 정해져있는 kernel thread라는게 있는 건지 궁금합니다.
좋은 퀄리티의 강의 감사합니다.
세승님 항상 강의를 좋게 봐주시고 또 열심히 봐주셔서 정말 감사합니다 :)
질문도 항상 이해하기 좋게 말씀해 주셔서 저도 여러모로 도움이 되네요 이것도 감사합니다 👍
1. 네, 맞습니다~ 말씀하신 내용을 저의 언어로 동일하게 표현해 보자면, 시스템 콜(I/O 작업도 시스템 콜을 통해 가능하다고 저는 알고 있습니다)을 실행해서 커널 코드가 실행되는 경우에, OS 스레드가 가상 메모리 공간에 있는 커널 스페이스에서 코드를 fetch 해서 CPU 코어에서 실행됩니다
2. 네, 첫번째로 말씀해주신 부분(>> "실제 os 커널이 수행하는 스케쥴링, 자원관리, 감시 등과 같은 것들을 말하는 것인지")이 맞습니다
강의 준비하면서 구글링을 해보니 하드웨어 이벤트 모니터링이나 디스크와 RAM 사이에 데이터 이동 등등의 커널이 하는 핵심 역할을 백그라운드에서 데몬처럼 수행하는 스레드를 커널 스레드라고도 하더라고요
그래서 혼란을 피하기 위해서, 흔히 os에서 관리하는 개발자가 쓸 수 있는 스레드를 OS 스레드, 혹은 native 스레드라고 부르는게 좋겠다 싶었어요
(이 문장은 다른 분들도 보실 수 있어서 참고로 남기는 건데요) 개발자가 작성한 코드가 실행되다가 시스템콜을 통해 커널 코드를 실행하게 될 때도, 그리고 다시 돌아와서 개발자가 작성한 코드를 실행하게 될 때도 모두 한 OS 스레드 안에서 처리됩니다
@@ezcd 감사합니다!
답변해주신 답을 토대로 질문 하나만 더 드리겠습니다 ㅎㅎㅎㅎ
1번의 답변중 커널 스페이스라고 불리는 가상메모리의 일정 reserved된 공간에 관한 내용에 대해서 공부를 해보려면 참고할만한 자료가 있을까요?
컴퓨터에 존재하는 모든 프로세스는 동일한 커널을 통해 커널단의 기능을 사용할테고, 그럴 경우에 커널 스페이스에 들어가있는 데이터가 모두 똑같을 것 같은데, 그러면 추후에 이를 실제 물리 메모리에 올려서 연산에 이용할때 중복으로 인해서 생기는 오버헤드가 있을 것 같아서요. 물론 이에 대한 해결책도 이미 마련되어있을 것 같구요!
위와 같은 주제로 다양한 공부할 내용이 있을 것 같은데, 혼자서 찾아서 검색해서 공부하려고 하니, 어떤 키워드로 접근을 해야 알맞은 정보를 얻을 수 있을지 의문이라 질문드립니다 ㅠㅠ
공유할만한 글을 찾아봤는데, 뭔가 깔끔하게 정리된 글은 잘 안보이네요.. ㅠㅠ
우선 답변을 드리면
>> 그럴 경우에 커널 스페이스에 들어가 있는 데이터가 모두 똑같을 것 같은데, 그러면 추후에 이를 실제 물리 메모리에 올려서 연산에 이용할때 중복으로 인해서 생기는 오버헤드가 있을 것 같아서요. 물론 이에 대한 해결책도 이미 마련되어있을 것 같구요!
네, 맞습니다~
첨언을 하자면 '커널 코드나 커널 코드 동작에 필요한 커널 데이터가 물리 메모리에 있다라고 한다면, 프로세스의 가상 메모리 공간의 커널 스페이스가 이 물리 메모리에 맵핑되는 형태로 동작한다'고 저는 이해를 하고 있어요.
그렇기 때문에 프로세스마다 커널 코드나 커널 데이터를 각자의 가상 메모리 공간의 커널 스페이스에 맵핑하는 형태로 '공유해서' 사용하기 때문에 중복된 코드나 데이터가 발생하지는 않을 것 같고요, 하지만 공유해서 사용하기 때문에 여러 프로세스가 같은 커널 코드를 우연히 동시에 실행했을 때, 이때 발생하는 데이터들은 프로세스 마다 자신들의 영역에 따로 저장을 해야할 것 같은데, (이 부분은 저도 아직 확실한 레퍼런스를 찾지는 못했고요,) 제 생각은 각자의 커널 스페이스에 일단 두지 않을까 싶어요. 그리고 유저 코드로 전달해야 하는 데이터라면 유저 스페이스로 복사하는 형태로 사용하지 않을까 짐작을 해봅니다 :)
--
요건 여담인데요, 보통 구글링은 한국어를 주로 하시나요? 아니면 영어로 주로 하시나요?
@@ezcd 우선적으로는 한글로 검색해보고 마땅한 자료가 없으면 영어로 찾습니다!
이런 주제들은 생각보다 지엽적인게 아니라 되게 well-known한 주제일거라고 생각하고 찾아봤는데 잘 안나오네요 ㅠㅠ...
@@세승-v4s 그렇군요~! 저는 아무래도 영어가 자료가 더 많기 때문에 보통 구글링을 영어로 하거든요~
세승님께도 영어로 먼저 해보시면 좀 더 빨리 찾으시는 정보에 도달하실 수 있지 않을까 싶어요 :)
👍 👍 👍
😆😆😆
뭐야 사랑해요
헤헤 👍
구독박고갑니다
사랑합니다