노션에 정리한 글을 블로그에 옮기는 중입니다..
Instrution
즉, 명령어를 실행한다.Fetch
한다.Decode
: 명령어가 무엇인지 해석한다.Execute
: 예를 들어 두 수를 더하고, 메모리에 접근하고, 조건을 검사하고, 함수로 이동하는 것 등등을 실행한다.💡 OS is in charge of making sure the system operates correctly and efficiently.
OS는 시스템이 정확하고 효율적으로 작동하는지 확인하는 역할을 담당한다.
OS는 CPU, memory, disk 등의 물리적인 자원들을 관리한다.
OS는 다음과 같은 것들을 허용한다.
CPU
를 공유하기 때문메모리
를 공유해서많은 프로그램들이 디바이스에 접근하는 것은 disk
를 공유하기 때문
CPU의 수는 제한되어 있기 때문에 가상화를 한다.
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h>
#include "common.h"
int main(int argc, char * argv[]_ }
if (argc != 2) {
fprintf(stderr, "usage: cpu <string>\n");
exit(1);
}
char *str = argv[1];
while(1) {
Spin(1); // 반복적으로 시간을 체크하고 1초에 한 번 씩 실행시킨다.
printf("%s\n", str);
}
return 0;
}
결과를 보면 입력받은 문자열을 1초마다 출력시킨다. Ctrl+C
를 누르면 프로그램 종료 가능
2번째 결과를 보면 ./cpu A &; ./cpu B &; ./cpu C &; ./cpu D &;
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
int main(int argc, char *argv[]) {
int *p = malloc(sizeof(int));
assert (p != NULL);
printf("(%d) address of p: %08x\n", getpid(), (unsigned) p);
*p = 0;
while (1) {
Spin(1);
*p = *p + 1;
printf("(%d) p: %d\n", getpid(), *p);
}
return 0;
}
prompt> ./mem &; ./mem &
[1] 24113
[2] 24114
(24113) memory address of p: 00200000
(24114) memory address of p: 00200000
(24113) p: 1
(24114) p: 1
(24114) p: 2
(24113) p: 2
(24113) p: 3
(24114)
위의 결과는 백그라운드로 두 개의 프로세스를 실행한 결과이다.
pid 값이 두개가 나온 것을 보아 프로세스 2개가 실행중이고
각각 address 값으로 00200000을 받았다. 그리고 각각 값이 1씩 증가하고 있다.
이것은 각각의 실행중인 프로그램이 own private memory를 가진것처럼 보인다.
각각의 실행중인 프로그램은 같은 주소
를 할당받았고
각각은 독립적으로 업데이트되고 있다.
각 프로세스는 자신만의 가상 주소 공간에 접근한다.
메모리를 공유하다 보면 동시성 문제가 발생한다.
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
volatile int counter = 0;
int loops;
void *worker(void *arg) {
int i;
for (i=0; i<loops; i++) {
counter++;
}
return NULL;
}
...
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: threads value\n");
exit(1);
}
loops = atoi(argv[1]);
pthread_t p1, p2;
printf("Initial value: %d\n", counter);
Pthread_create(&p1, NULL, worker, NULL);
Pthread_create(&p2, NULL, worker, NULL);
Pthread_join(p1, NULL);
Pthread_join(p2, NULL);
printf("Final value: %d\n", counter);
return 0;
}
prompt> gcc -o thread thread.c -Wall -pthread
prompt> ./thread 1000
Initial value : 0
Final value : 2000
→ loops : 1000이라는 값을 줬을 때 두 개의 스레드가 실행되어 두개가 각각 카운터 값을 증가시켰기에 2000이라는 값을 얻는다.
prompt> ./thread 100000
Initial value : 0
Final value : 143012 // huh??
prompt> ./thread 100000
Initial value : 0
Final value : 137298 // what the??
→ loops: 100000 값을 줬을 때 예상 값이랑 다르게 나오는데 이게 바로 concurrency 문제이다.
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
int fd = open("/tmp/file", O_WRONLY | O_CREATE | O_TURNC, S_IRWXU);
assert(fd > -1);
int rc = write(fd, "hello world\n", 13);
assert(rc == 13);
close(fd);
return 0;
}
open(), write(), close() 와 같은 시스템 콜은 요청을 처리하는 파일시스템이라는 OS 부분으로 라우팅된다.
디스크에 쓰기 위해 OS는 무엇을 할까?
파일 시스템은 쓰기 중에 나타나는 system crash를 처리한다.