포스트

2021-01-22-TIL

운영체제 수업을 들으며 받아 적은 메모와, 수업 뒤에 찾아본 자료를 주제별로 묶었다.


스레드와 멀티코어

노드는 싱글 스레드라서 스레드 슬립

동기화/비동기화

메모리 지역성

분할정복할 수 있는 문제의 경우에는 병렬적으로 처리할 수 있다.

싱글코어에서 멀티스레드는 만개까지는 빨라진다.

같은 질문을 다룬 Stack Overflow 답변은 싱글코어에서 스레드를 늘려도 계산이 빨라지기를 기대할 수 없고 오히려 느려진다고 본다. 멀티스레드를 쓰는 이유는 여러 코어를 병렬로 쓰기 위해서이거나, 여러 입력을 기다리는 프로그램의 구조를 단순하게 만들기 위해서라는 설명이다. 수업에서 말한 “빨라진다”는 I/O 대기처럼 CPU가 노는 시간이 있는 경우로 읽어야 한다.

SMT, 하이퍼스레딩, AMD에서는

SMT(simultaneous multithreading)는 한 물리 코어가 여러 하드웨어 스레드의 명령을 동시에 처리하는 기술이다. 위키백과에 따르면 Intel은 이 기능을 Hyper-Threading Technology라고 부르고, 2002년 Pentium 4 3.06GHz 모델부터 데스크톱에 도입했다. AMD의 Zen 계열은 2-way SMT를 지원한다.

왜 게임은 싱글스레드로 밖에 못 돌리나

1번 코어만 많이 쓰는데 1번 코어만 닳고 그럴 수도 있어요? 그런 경우는 물리적으로 거의 없다.

리눅스 커널 내부구조

GC가 성능이 안 나와서 GC를 고를 수가 있다. 하지만 해결이 안 되어서 C언어로 APP을 짜서 Java에서 직접 C API를 호출하는 방식으로 해결


공부하는 방법

야크 쉐이빙과 같이 공부해라. 키워드만 중심으로 하라. 모르면 모르는 상태로 넘어가라. 농구도 드리블 한 달, 패스 한 달, 이런 식으로 하지 않는다. 그러다 보면 어느 날 갑자기 되는 기술이 생기기도 한다.


운영체제의 목적과 가상 메모리

OS의 목적 HW제어, Protection 리소스 보호

VM 가상메모리 - 콘도 overbooking과 비슷, 페이징

요구 페이징 시스템은 프로세스가 특정 페이지를 요구할 때 그 페이지를 물리 메모리에 올린다. 필요한 페이지가 메모리에 없으면 페이지 부재(page fault)가 나고, 빈 프레임이 없으면 내보낼 페이지를 골라야 한다. 참고한 글은 이 선택 기준으로 가장 오래 전에 올라온 페이지를 내보내는 FIFO, 앞으로 가장 오래 쓰이지 않을 페이지를 내보내는 최적(Optimal) 교체, 가장 오래 사용되지 않은 페이지를 내보내는 LRU를 비교한다. 최적 교체는 미래의 참조를 알아야 하므로 실제 구현보다 비교 기준으로 쓰인다.


fork, exec, source

fork()는 호출한 프로세스를 복제해 새 프로세스를 만든다. 아래처럼 무한히 fork()하는 코드는 프로세스 테이블을 가득 채운다. 메모에는 for()로 적혀 있었는데 fork()의 오타다.

1
2
3
while (true) {
    int pid = fork(); // 65500 정도로 제한하면 ssh로 접속해서 kill할 수 있다.
}

스미스 요원이 fork() 해서 막 복제한 다음 exec()하는 것. 컴퓨터 공부를 하고 다시 보는 영화를 리뷰 해야지.

연산이 많지 않아서 부모가 먼저 죽을 가능성이 크다. 핵심 연산은 자식이 담당하므로

export $PYRO

source 명령은 출력된다. source는 한 줄씩 명령을 현재 쉘에서 실행하는 것이다. 그러므로 fork()를 하지 않는다. . test.sh 점은 source의 준말이다.

Bash 매뉴얼은 . 명령이 파일의 명령을 현재 셸 컨텍스트에서 읽어 실행한다고 설명하고, source를 .의 동의어로 정의한다. 반면 실행 권한이 있는 스크립트를 그냥 실행하면 Bash가 자기 자신의 새 인스턴스(서브셸)를 만들어 실행하므로 그 안에서 바꾼 환경 변수가 부모 셸에 남지 않지만, source로 실행하면 현재 셸의 변수가 바뀐다.


스레드의 구조와 스케줄링

스레드는 preempt 하는가?

파직스(POSIX) 스레드

스레드의 확대 -> PC와 Register Backup이 필요, 메모리의 코드영역은 공유한다, 스택은 나눠서 각자 쓴다, 힙은 공유

pthreads(7) 매뉴얼도 같은 구조를 설명한다. 한 프로세스의 스레드들은 같은 프로그램을 실행하고 전역 메모리(데이터와 힙 세그먼트)를 공유하지만, 스레드마다 자기 스택을 가진다.

리눅스가 프로세스를 스케줄링하는지 스레드를 스케줄링하는지에 대한 Stack Overflow 답변은, 리눅스 스케줄러의 단위가 태스크이고 멀티스레드 프로세스의 각 스레드도 싱글스레드 프로세스와 같은 방식으로 스케줄링된다고 설명한다. Java 스레드가 유저 영역과 커널 영역 중 어디에 만들어지는지는 JVM 구현마다 다르다는 답변이 달려 있다.


Java의 모니터와 동기화

JLS 17장에 따르면 Java의 기본 동기화 수단은 모니터다. 모든 객체는 모니터와 연결되어 있고, 한 번에 한 스레드만 모니터의 락을 가질 수 있으며 다른 스레드는 락을 얻을 때까지 블록된다. synchronized 블록이 이 락을 사용하고, wait()와 notify()도 객체의 모니터를 통해 스레드끼리 신호를 주고받는다.

wait()는 Object의 메서드라서 synchronized 문맥 안에서 호출해야 하고, 그렇지 않으면 IllegalMonitorStateException이 난다. join()은 Thread의 메서드로, 호출 대상 스레드가 끝날 때까지 현재 스레드를 기다리게 해 실행 순서를 정한다.

뮤텍스는 열쇠 하나를 가진 스레드만 공유 자원에 들어가는 방식이고, 세마포어는 공유 자원에 동시에 접근할 수 있는 수를 값으로 두고 그 값을 줄이고 늘려 상호 배제를 이루는 방식이다.


Node.js 이벤트 루프

Node.js 문서에 따르면 이벤트 루프는 JavaScript 스레드가 기본적으로 하나뿐인데도 논블로킹 I/O를 할 수 있게 해 주는 장치이고, 가능한 작업은 커널에 넘긴다. 루프는 setTimeout()과 setInterval() 콜백을 실행하는 timers, 새 I/O 이벤트를 받아 콜백을 실행하는 poll, setImmediate() 콜백을 실행하는 check, close 콜백 단계 등을 차례로 돈다. 그래서 콜백 하나가 오래 걸리면 다음 단계의 타이머 콜백도 늦어진다.


그 밖의 메모

pbcopy, pbpaste: macOS에서 표준 입력을 클립보드에 넣고(pbcopy), 클립보드 내용을 표준 출력으로 꺼내는(pbpaste) 명령이다.

pintOS, natchOS: Pintos는 Stanford CS140에서 쓰는 x86용 교육 운영체제 프레임워크로, 커널 스레드와 사용자 프로그램 실행, 파일 시스템을 단순하게 구현해 두고 과제에서 보강하게 한다.

boxer

콘웨이의 라이프게임: 각 칸이 살아 있거나 죽어 있는 2차원 격자에서, 이웃 여덟 칸의 상태에 따라 다음 세대가 정해지는 셀룰러 오토마톤이다.

오징어 타는 냄새가 났다고 하니깐 당연하지 오징어가 타고 있으니깐

cmatrix

공부 사이트: Nand to Tetris는 논리 게이트부터 시작해 범용 컴퓨터와 소프트웨어 계층을 직접 만들어 보는 강의 자료와 도구를 제공한다.

참고한 자료외부 출처 37

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다