(제약 조건이 있는 환경: CPU가 여러 개 있는 환경)
여러 CPU들이 있는 상황에서 여러 CPU가 균형있게 골고루 일을 하게 하는것과
잡들이 몰리지 않도록 로드 쉐어링을 해주는 것이 중요
각 CPU마다 줄을 별도로 세우는 방법
한 줄로 세워놓고 맨 앞단 비면 꺼내가는 방법
Symmetric Multiprocessing(대칭)
CPU 들이 다 대등하게 일을 한다
각 CPU들이 알아서 일을 한다 균일한 일들을 한다
비효율적 측면 존재
Asymmetric Multiprocessing(비대칭)
한 개의 CPU가 대장 CPU(브레인)가 되어서 나머지는 그 결정에 따라서 일을 한다
주어진 시간 안에 꼭 끝내야 하는 것
우리가 일반적으로 쓰는 컴퓨터와 운영체제는 리얼타임이 아니다
데드라인 어기면 큰일 => 반드시 시간을 어기지 않게 미리 설계해야 한다
데드라인은 있지만 어겼을 때 약간의 불편만 발생
무조건 데드라인 지켜야 하는 것은 아닌 시스템
SJF(짧은 프로세스가 우선순위 높은 것)는 데드라인 없었다
만약 리얼타임 스케줄링 이라면 도착시간 뒤에 데드라인이라는 조건을 포함
7초 쓰고 싶은데 데드라인이 20초 그 안에 CPU 를 6초밖에 못줬으면 데드라인 어기는 것
제대로 된게 아니다
빨리 처리하는 것보다 데드라인을 만족시키는게 중요!
스레드 하나의 프로세스 안에 CPU 수행 단위가 여러 개 있는 것
즉, 운영체제가 스레드의 존재를 안다면 직접 스레드를 결정하고
모른다면 프로세스 내부에서 스레드를 지목한다
수식을 계산해서 성능 척도 값을 알아내는 방법
실제로 측정해서 알아내는 측정 방법
내가 만든 알고리즘 증명한다면 >
리눅스의 공개 소스코드의 CPU 스케줄링 코드 활용하여내 알고리즘으로 바꾸고 컴파일 >
오리지널 리눅스 설치한 컴퓨터와 내 알고리즘을 심은 컴퓨터에서 프로그램을 돌려서 성능척도의 결과를 확인
어려운 구현의 대안이 되는 방법
시스템 구현하는게 아니라 가상으로 돌려보는 것
컴퓨터 안에서 연산이 이루어질 때
1. 데이터 읽어와서 연산
2. 결과를 어딘가에 저장
3. 메모리에 있는 데이터 읽어와서 CPU(왼쪽)에서 연산
4. 다시 데이터를 메모리(오른쪽)로 가져다가 사용
위와 같은 방식으로 I/O를 하는 하드디스크의 파일 읽어와서 내부 작업하고 내보낸다
데이터를 읽어들어와서 일을 하고 결과를 내보내는 형식
데이터를 여러 곳에서 읽어가서 연산하게되면 레이스 컨디션 문제가 발생 !
가운데 저장되어있는 count라는 변수 값
먼저 왼쪽에서 1 증가시키는 연산을 하고 다시 저장
오른쪽에서 1 감소시키는 연산을 하고 다시 저장
count 값은 1 증가 1 감소로 인해 원래 값이 저장되어 있어야 한다
연산할 주체 둘이 있는 경우,
1 증가시키는 도중 카운트 값을 읽어감 > 연산이 끝나서 저장하면 1 증가
다른 곳에서 1 증가 시키기 이전의 값을 읽어감 > 1을 뺀 다음에 최종적으로 저장
모든 연산이 반영되지 않고 도중에 읽어가서 연산하고 저장한 감소만 반영된다
문제가 생기지 않는다는 관점
문제가 생기는 관점 (운영체제가 끼어드는 경우)
CPU 개수 상관없이 레이스 컨디션이 발생한다 (CPU가 한 개인 경우라도)
A 실행중 >
A 프로세스가 본인이 할 수 없는 일을 운영체제한테 시스템 콜을 해서 요청 >
운영체제 안의 데이터 값을 바꾸고 있는 상황 >
CPU 할당 시간 끝나면 A에서 B로 넘어감 >
B가 실행도중 B도 본인이 할 수 없는 일을 하게 되어서 운영체제한테 시스템 콜 >
B의 요청에 의해서 또다시 운영체제 코드 실행해서 변수 변경 (똑같은 데이터 건드려야 하는 상황) >
CPU가 A한테 다시 간다면 운영체제 작업하다 만 일을 계속 진행 (그 다음 CPU 기계어부터 시작)
즉, 시스템 콜 해서 운영체제가 커널 데이터 건드리는 도중에 CPU가 다른 프로세스한테 넘어가면 문제가 생길 수 있다
문제 해결하기 위해 변수를 변경하기 전에 인터럽트 disable 시키고 하던 작업이 끝나면 인터럽트를 받는다
커널의 공유 변수 건드리기 전에 disable 시키고 끝나면 인터럽트를 수용
커널 모드에서 수행중일 때는 CPU를 빼앗지 않는다
CPU 시간이 끝나도 커널모드의 작업 모두 끝내고 유저 모드로 돌아갈 때 CPU를 넘겨주도록 한다
운영체제는 타임 쉐어링 시스템에서 모두가 행복하자고 만든 것
CPU를 빼앗는 것은 커널 모드에서 일하고 있으면 그 작업 끝난 다음에 CPU를 빼앗자
정리
프로세스 간에는 주소공간 공유하지 않는다고 했는데 레이스 컨디션 문제가 왜 발생?
시스템 콜을 통해 운영체제 들어가서 작업 처리할 때 문제 발생할 수 있다
공유 메모리를 쓰면 메모리 주소공간 일정부분 공유하기 때문에 프로세스가 공유 메모리 안의 변수를 건드리는 도중에 CPU를 빼앗겨서 넘기면 원하지 않는 결과가 나올 수 있다
공유 메모리 쓰는 개별 프로세스가 실행 도중에 CPU 뺏기더라도 문제가 생기지 않도록 코딩해야 한다 => 이후 나오는 프로세스 싱크로나이제이션과 관련된 테크닉
공유데이터의 동시접근으로 생기는 문제
멀티 프로세서(CPU가 여러 개 있는 상황)에서 운영체제가 실행될 때 프로세스 싱크로나이제이션이 발생할 수 있다
프로세스가 각자의 주소공간을 가지고 일하면 문제없지만 운영체제 코드를 양쪽에서 건드려서 문제가 생길 수 있다 => 데이터 불일치 문제
CPU 자체가 여러 개 있다면 한 쪽의 인터럽트를 막아도 다른 쪽에서 읽어갈 수 있다
운영체제 코드가 수행중이면 다른 어떤 CPU도 운영체제를 못들어가게 하는것
문제 원인은 운영체제 동시 접근해서 생기는 것
공유데이터 각각에 lock을 걸어서 접근하지 못하게 한다
1번 방법은 운영체제 전체를 락 걸어서, 카운트 접근 못하게 하면 혼자만 독점해서 쓰고 다른 친구가 못 쓰게 하는 방법
2번 운영체제 안에 여러 개의 데이터가 존재하고 각 데이터별로 사용중일 때 락 걸고 사용이 끝나면 락 풀게 하는 방법
여러 CPU가 운영체제 수행중이더라도 해당 데이터를 건드리고 있지만 않다면 충분히 운영체제 코드를 동시에 사용할 수 있다
협력하는 프로세스 간의 실행 순서를 정해주는 것이 필요하는 것이 중요하다
1번 프로세스와 2번 프로세스 존재
x=2 일 때 하나는 1 증가시키고 싶고, 하나는 1 감소시키고자 한다
(고급 언어에서의 한 문장이 기계어로 바뀌면 여러 개의 기계어로 나누어서 실행이 된다)
메모리 변수 X는 먼저 레지스터에 읽혀져서 레지스터 값을 증가시키고 그 다음에 그 값을 다시 메모리에 저장
값이 원자적으로 실행되면 문제가 없지만 실행하는 도중에 쪼개져서 CPU가 다른 프로세스한테 넘어갈 수 있다는게 문제