Study/TIL(Today I Learned)

24.03.17 운영체제, PintOS

에린_1 2024. 3. 17. 22:26
728x90

운영체제

20. 병행성 : 개요

  • 하나의 쓰레드의 상태는 프로세스의 상태와 매우 유사하다. 쓰레드는 프로그램 카운터와 연산을 위한 레지스터들을 가지고 있다. 만약 두 개의 쓰레드가 하나의 프로세서에서 실행 중이라면 실행하고자 하는 쓰레드는 반드시 문맥교환을 통해 실행중인 쓰레드와 교체 되어야 한다. 프로세스의 쓰레드들의 상태를 저장하기 위해서는 하나 또는 그 이상의 쓰레드 제어블럭(TCB : thread control block)이 필요하다. 프로세스와의 가장 큰 차이는 프로세스의 경우와 달리 쓰레드간의 문맥 교환에서는 주소공간을 그대로 사용한다는 것이다.(사용하고 있던 페이지 테이블을 그대로 사용하면 된다.)
  • 쓰레드와 프로세스의 또 다른 차이는 스택에 있다. 고전적 프로세스 주소 공간과 같은 모델(단일 쓰레드 프로세스)에서는 스택이 하나만 존재한다.
  • 반면에 멀티 쓰레드 프로세스의 경우에는 각 쓰레드가 독립적으로 실행되며 쓰레드가 실행하기 위해 여러 루틴들을 호출할 수 있다. 주소 공간에는 하나의 스택이 아니라 쓰레드마다 스택이 할당 되어있다. 두 개의 쓰레드를 가지는 멀티 쓰레드 프로세스의 주소 공간은 단일 프로세스의 주소공간과는 다르다.
  • 스택에 할당되는 변수들이나 매개변수, 리턴 값, 그리고 그외에 스택에 넣는 것들은 해당 쓰레드의 스택인 쓰레드-로컬 저장소(thread - local storage)에 저장된다.

20.1 왜 쓰레드를 사용하는가?

  • 병렬처리(Parallelism)
    • 단일 프로세서에서 실행하는 경우 작업은 간단하다. 각 작업을 하나씩 수행하고 완료하면 된다. 그러나 멀티 프로세서 시스템에서 프로그램을 실행하는 경우 각 프로세서가 작업의 일부분을 수행하게 함으로써 실행속도를 상당히 높일 수 있다. 표준 단일 쓰레드(single-threaded) 프로그램을 멀티 프로세서 상에서 같은 작업을 하는 프로그램으로 변환하는 작업을 병렬화(Parallelization)라고 부르며, CPU마다 하나의 쓰레드를 사용하여 주어진 일을 하는것이 최신 하드웨어 상에서 프로그램을 더 빠르게 실행하게 만드는 자연스럽고 전형적인 방법이다.
  • 느린 I/O
    • 느린 I/O로 인해 프로그램 실행이 멈추지 않도록 하기 위해 쓰레드를 사용한다. 다른 종류의 I/O를 수행하는 프로그램을 기다리는 대신 프로그램은 다른 작업을 수행할 수 있다. 다른 작업에는 CPU가 다른 연산을 수행한다거나 심지어 또 다른 입출력 요청등이 포함된다.
    • 쓰레드를 사용하면 진행이 막히는 것을 자연스럽게 피할 수 있다. 여러분의 프로그램 중 하나의 쓰레드가 대기하는 동안, CPU 스케줄러는 다른 쓰레드로 전환 할 수 있고, 이 쓰레드는 준비 상태이며, 유용한 작업을 수행한다. 쓰레딩은 하나의 프로그램 안에서 I/O와 다른 작업이 중첩(overlap)될 수 있게 한다. 이는 여러 프로그램을 대상으로 프로세스를 멀티 프로그래밍(multi programming)하는것과 비슷하다.

20.2 예제 : 쓰레드 생성

  • 쓰레드 생성을 생각하는 한 가지 방법은 쓰레드의 생성이 함수를 호출하는 것과 비슷하다고 생각하는 것이다. 함수 호출에서는 함수 실행후에 호출자(caller)에게 리턴하는 반면에 쓰레드의 생성에서는 실행할 명령어들을 갖고있는 새로운 쓰레드가 생성되고, 생성된 쓰레드는 호출자와는 별개로 실행된다. 쓰레드 생성 함수가 리턴되기전에 쓰레드가 실행될 수도 있고, 그보다 이후에 실행 될 수도 있다. 다음에 실행될 쓰레드는 OS 스케줄러에 의해 결정되며, 특정 순간에 어떤 쓰레드가 실행될지 알아내는 것은 어렵다.

20.3 데이터 공유 문제

  • 명령어의 실행 순서에 따라 결과가 달라지는 상황을 경쟁조건(race condition)이라고 한다. 컴퓨터의 작동에서 일반적으로 발생하는 결정적 결과와 달리 결과가 어떠할지 알지 못하거나 실행할 때마다 결과가 다른 경우를 비결정적(indeterminate)인 결과라고 부른다.
  • 멀티 쓰레드가 같은 코드를 실행할 때 경쟁조건이 발생하기 때문에 이러한 코드 부분을 임계영역 이라고 부른다. 공유변수를 접근하고 하나 이상의 쓰레드에서 동시에 실행되면 안되는 코드를 임계영역이라고 부른다.
  • 이러한 코드에서 필요한 것은 상호배재(mutual exclusion)이다. 이 속성은 하나의 쓰레드가 임계영역 내의 코드를 실행중일 때는 다른 쓰레드가 실행할 수 없도록 보장해준다.

PintOS

  • 로직과 코드가 맞는 것같은데 안됐던 이유를 찾아냈다.
  • init.c 파일에 print문이 원래 있었는데, 어떤 작업을 하다가 이것을 지워버렸던 것 같다.
  • 켜주니 write함수가 그래도 잘 작동해서 halt, exit외에도 여러 테스트를 통과했다.
bool create (const char *file, unsigned initial_size)
{
	
	if(file == NULL || pml4_get_page(thread_current()->pml4, file) == NULL || !is_user_vaddr(file) || *file == '\\0' )
		exit(-1);
	
	bool success = filesys_create(file,initial_size);
	return success;
}

int open (const char *file)
{
	if(file == NULL || pml4_get_page(thread_current()->pml4, file) == NULL || !is_user_vaddr(file) || *file == '\\0')
		exit(-1);
	struct file* f = filesys_open(file);
	
}
  • create를 만들고 open을 구현중이다. fd를 어떻게 해줘야할지 여러 고민을 하고 있다.
  • pml4_get_page을 포함하여 여러 조건을 통해서 예외처리를 해줬다.
case SYS_CREATE:
		f->R.rax = create(f->R.rdi,f->R.rsi);
		break;
	
  • 반환값을 다시 f→R.rax로 돌려줘야 이 프로세스가 반환값을 받을 수 있는데, 이것을 놓치고 있었다. 기초적인 부분에서 실수를 줄이도록 하자.
pass tests/threads/priority-donate-chain
pass tests/userprog/args-none
pass tests/userprog/args-single
pass tests/userprog/args-multiple
pass tests/userprog/args-many
pass tests/userprog/args-dbl-space
pass tests/userprog/halt
pass tests/userprog/exit
pass tests/userprog/create-normal
pass tests/userprog/create-empty
pass tests/userprog/create-null
pass tests/userprog/create-bad-ptr
pass tests/userprog/create-long
pass tests/userprog/create-exists
pass tests/userprog/create-bound
pass tests/userprog/open-normal
FAIL tests/userprog/open-missing
pass tests/userprog/open-boundary
FAIL tests/userprog/open-empty
pass tests/userprog/open-null
pass tests/userprog/open-bad-ptr
pass tests/userprog/open-twice
pass tests/userprog/close-normal
pass tests/userprog/close-twice
pass tests/userprog/close-bad-fd
FAIL tests/userprog/read-normal
FAIL tests/userprog/read-bad-ptr
FAIL tests/userprog/read-boundary
FAIL tests/userprog/read-zero
pass tests/userprog/read-stdout
pass tests/userprog/read-bad-fd
FAIL tests/userprog/write-normal
FAIL tests/userprog/write-bad-ptr
FAIL tests/userprog/write-boundary
FAIL tests/userprog/write-zero
pass tests/userprog/write-stdin
pass tests/userprog/write-bad-fd
FAIL tests/userprog/fork-once
FAIL tests/userprog/fork-multiple
FAIL tests/userprog/fork-recursive
FAIL tests/userprog/fork-read
FAIL tests/userprog/fork-close
FAIL tests/userprog/fork-boundary
FAIL tests/userprog/exec-once
FAIL tests/userprog/exec-arg
FAIL tests/userprog/exec-boundary
FAIL tests/userprog/exec-missing
pass tests/userprog/exec-bad-ptr
FAIL tests/userprog/exec-read
FAIL tests/userprog/wait-simple
FAIL tests/userprog/wait-twice
FAIL tests/userprog/wait-killed
pass tests/userprog/wait-bad-pid
FAIL tests/userprog/multi-recurse
FAIL tests/userprog/multi-child-fd
FAIL tests/userprog/rox-simple
FAIL tests/userprog/rox-child
FAIL tests/userprog/rox-multichild
FAIL tests/userprog/bad-read
FAIL tests/userprog/bad-write
FAIL tests/userprog/bad-read2
FAIL tests/userprog/bad-write2
FAIL tests/userprog/bad-jump
FAIL tests/userprog/bad-jump2
FAIL tests/filesys/base/lg-create
FAIL tests/filesys/base/lg-full
FAIL tests/filesys/base/lg-random
FAIL tests/filesys/base/lg-seq-block
FAIL tests/filesys/base/lg-seq-random
FAIL tests/filesys/base/sm-create
FAIL tests/filesys/base/sm-full
FAIL tests/filesys/base/sm-random
FAIL tests/filesys/base/sm-seq-block
FAIL tests/filesys/base/sm-seq-random
FAIL tests/filesys/base/syn-read
FAIL tests/filesys/base/syn-remove
FAIL tests/filesys/base/syn-write
FAIL tests/userprog/no-vm/multi-oom
pass tests/threads/alarm-single
pass tests/threads/alarm-multiple
pass tests/threads/alarm-simultaneous
pass tests/threads/alarm-priority
pass tests/threads/alarm-zero
pass tests/threads/alarm-negative
pass tests/threads/priority-change
pass tests/threads/priority-donate-one
pass tests/threads/priority-donate-multiple
pass tests/threads/priority-donate-multiple2
pass tests/threads/priority-donate-nest
pass tests/threads/priority-donate-sema
pass tests/threads/priority-donate-lower
pass tests/threads/priority-fifo
pass tests/threads/priority-preempt
pass tests/threads/priority-sema
pass tests/threads/priority-condvar
pass tests/threads/priority-donate-chain
49 of 95 tests failed.
  • 진행상황
728x90

'Study > TIL(Today I Learned)' 카테고리의 다른 글

24.03.19 퀴즈, 운영체제, PintOS  (1) 2024.03.19
24.03.18 운영체제, KEYWORD, PintOS  (1) 2024.03.19
24.03.16 운영체제, PintOS  (1) 2024.03.16
24.03.15 운영체제, PintOS  (1) 2024.03.16
24.03.14 운영체제, PintOS  (1) 2024.03.15