3학년 2학기 4주차 스레드수업
0.
overview
크게 single, multithreaded processes로 나뉜다.
지금까지 우리는 sigle threaded process를 배워왔다.
multithreaded는 한 개의 프로세스에 여러 개의 스레드가 동시에(concurrent)하게 실행된다는 뜻이다.
하나의 프로세스에는 registers(mov,add...를 위해서), code(text), data, stack, heap, files 처럼 resource를 가지고 있다.
이런 resource는 pcb에 있었다. 그러나 다 pcb에 있는 게 아니고 주소나 정보만 있고 실제로는 다른 곳에 있는 거다.
( linux는 task_struct )
프로세스 안의 모든 쓰레드는 다음과 같은 항목을 공유한다. -> code, data, files
address space (옆에 그림에서 보듯이 공간 stack, heap, data, text...)
global variables (전역 변수)
open files (파일들)
child processes (자식 프로세스)
(밑에는 참고만)
pending alarms
signal handlers
accounting information (system call을 몇 번했고..)
쓰레드가 개인적으로 가지고 있는 것은 아래와 같다.
program counter(레지스터)
registers
stack(로컬변수)
state (ready, wait, run ... 프로세스의 상태)
이 중에서 register과 stack을 보자.
스레드끼리 context switching이 일어난다고 생각해보자
아까 어디까지 실행됐더라 하고 pc(register)가 따로따로 저장해놔야겠다.
스택은 로컬변수가 다 따로따로 존재해야하니깐~
그래서 레지스터, stack도 따로따로 저장하더라
그럼 data는? 글로벌,static 변수는 프로그램 전체에 영향을 주니깐 공유가 된다.
모든 함수에서 전역변수는 공유되니깐
file은 당연히 공유되는 것이지.
그러면 쓰레드를 사용하면 이점은 무엇인가?
responsiveness
-> multi process vs multithread로 생각하면 process는 Resource가 많아서 fork하면 너무 무겁다..
바로 반응을 못해주지..
resource sharing
-> process에서는 resource가 공유되는 것이 없지만 쓰레드는 공유하는 것이 있다.
economy
-> 당연히 경제적이다. 100개의 프로세스면 1000개의 쓰레드가 가능하지.
프로세스 생성을 위해 메모리와 자원을 할당하는 것은 비용이 많이든다. 스레드는 공유하기때문에 스레드를 생성하고 문맥교환하는 것이 경제적이다. (완벽하게 오버헤드를 비교할 수는 없다.)
utilization of mp architectures
-> multi processors architectures(multi core)를 활용하기 쉽다.
다중스레드의 이점은 다중 처리기 구조에서 더욱 증가한다. 왜냐하면 multi processors architecture에서는 각각의 스레드가 다른 처리기에서 병렬로 수행될 수 있기때문이다.
그래서 위와 같은 이유덕분에 멀티스레드가 발전하게 되었다.
스레드를 구분해보자면 2개의 스레드로 나뉜다.
1.
user threads
스레드 관리가 user 수준의 라이브러리에서 일어나는 것.
사용자가 만든 것이다.
라이브러리에는 3가지가 있다.
-posix pthreads: unix계열에서 많이 쓰이는 것이다.
-win32 threads: 윈도우 계열의 스레드
-java threads: 언어자체에 스레드를 만드는 기능이있다.
2.
kernel threads (백그라운드)
kernel(자원관리자)로 부터 지원받는 쓰레드다.
예시, 리눅스, 윈도우, 맥 운영체제 등등
3.
pthreads
posix: 리눅스에서 제공하는 unix api를 표준화한 것이다.
(왜? unix종류가 많아서 헷갈리기때문에 한번 정리를 한 것이다.)
unix는 종류가 많다
예를 들어서, solaris, linux, mac os...
명령어(system calls, function calls)로는...
pthread_create -> fork(), exec() 처럼 생성
pthread_exit -> exit()
pthread_join -> wait() 처럼 특정 쓰레드가 끝날때까지 기다린다.
pthread_yield -> sched_yield() 스케쥴링을 위함.
pthread_attr_init -> attribute를 세팅
pthread_attr_destroy
1)posix threads 실습하기
(figure 2-15 참고)
gcc thread.c -o thread -lpthread (컴파일과 링크를 동시에 한다.)
standard library는 컴파일할때, -lc가 붙는 데 생략되는 반면 pthread는 생략되지않고 뒤에 -lpthread가 붙는다
#include <pthread.h>
메인함수에서는 pthread_t을 이용한다. 사실은 int
pthread_creat메소드를 이용해서 만드는데 첫 번쨰 인자로 스레드의 아이디가 리턴된다. (그래서, &로 넘겨준다)
두번째는 그냥 널로하고, 3번째는 print_hello_world인데, 스레드를 하나 만들어서 이 함수를 실행하라는 말이지
(리눅스로 생각하면 fork 랑 exec를 합친다. 함수의 인자는 4번쨰 인자 void *를 말한다.
스레드 만들고 4번째 인자를 인자로 보내서 함수를 실행시킨다.
두 코드의 차이점?
pthread_create()
print_hello_world()
concurrent하게 실행되는데, 한 개의 main thread에 여러 function thread가 실행된다.
스레드는 총 11개이다.
= 11개 스레드/1 프로세스
그냥 function call을 하면 옆의 그림처럼 메인 스레드가 더 이상 진행되지 못한다.
= 1개의 스레드/1 프로세스
2)
function: pthread_create
(thread item을 포인터타입으로 받아온다,attribute,함수명(function pointer),함수인자)
(cf. function이름 = function의 시작 주소)
function: pthread_exit
프로세스 exit하고 다른게 다양한 타입의 인자를 준다.
메인스레드한테 넘길 어드레스를 넘겨준다.
function: pthread_join
프로세스의 wait와 비슷하다.
(스레드의 아이디: 어떤 스레드를 wait하겠다, 이중포인터(받은 포인터변수를 가리키는 포인터변수)로 받는다)
자식스레드가 끝나면 Exit에서 값을 넘겨주는데 그걸 join(wait)에서는 포인터로 받아줘야한다.
3)simple threaded program(예제)
a_thread: 스레드 아이디 저장하는 걸 아까와 달리 하나만 만들었다.
스레드만들어서 function을 불러라 인자는 메시지를 보낸다.
받는 입장에서는 (char)로 형변환을 해줘야한다. 여기서 왜 (void *)를 하는 거지? 22분
그럼 예제를 실행해보자 -> gcc thread1.c -o thread1 -lpthread
동시에 막 실행되니깐 어떤게 먼저 실행될지 모른다.(커널이 순서를 정해준다.)
pthread_exit((void *) "Thank you")이 부분은 우리가 문자열을 넘겨줄때 첫 주소를 넘겨주는 거라서 포인터로 넘겨주는데 ...(char *) , 원래 exit함수의 인자가 (void *)로 되어 있기때문에 경고뜨기 싫어서 그냥 (void *)로 형변환(type casting) 한다.
join을 통해서 a_thread를 wait하고, thread_result에 넘겨준다.
a_thread는 기다리다가 thread_function이 끝나면 밑으로 이동한다.
실습해보세용~
4)simultaneous execution of two threads(예제)
헤더파일은 생략되어 있다.
create하는 순간 두 개의 스레드가 진행중이다.
메인스레드와 함수스레드
번갈아가게 출력하려고 전역변수를 1과 2로 번갈아가며 출력한다.
학생의 질문
20초 뒤에 한번에 출력된다 왜 그렇냐?
버퍼캐시 메카니즘이 있어서 버퍼에 다 쌓아놓고 한번에 출력하는 경우가 생긴다.
그런 경우에는 printf 다음줄에 fflush(stdout)을 넣어주면 해결된다.
(버퍼캐시에 있는 것을 넘겨버린다.)
참고 쓰레드 개념 완벽정리
joinc.co.kr/w/Site/system_programing/Book_LSP/ch07_Thread
리눅스 시스템 프로그램밍 7장 쓰레드
Process, Kernel Thread, User Thread
joinc.co.kr:443
참고 pthread join, exit 인자에 대해서 완벽정리
쓰레드시 pthread_exit으로 pthread_join에 값 넘기는 경우 | KLDP
글쓴이: 익명 사용자 / 작성시간: 토, 2002/06/15 - 9:08오전 지금 geekforum에서도 진행되고 있지만 아래의 프로그램 중 포인터에 대 해 정확히 제가 이해 하고 있지 못해서 질문을 올립니다. pthread_join��
kldp.org
'이제는 사용하지 않는 공부방 > Operating system' 카테고리의 다른 글
| [운영체제] process creation3 (0) | 2020.09.16 |
|---|---|
| [운영체제] exec, wait (0) | 2020.09.16 |
| [운영체제] process creation (0) | 2020.09.16 |
| [운영체제] 리눅스란 (0) | 2020.09.12 |