티스토리 뷰
일전에 이런 내용을 다룬 적이 있다.
2013/02/15 - [About School] - [Study] Task / Thread
그 때 이야기 하기론 thread는 Process를 처리하는 일종의 Worker의 개념으로 설명했었다. 당연히 이 Thread가 여러개 있어서 concurrent하게 Process를 처리하는 구조인 MultiThread를 지향하는 방향이다. 물론 Process가 어떤 위치에 있느냐에 따라서 Thread의 중요성도 다를 것이다. 예를 들어 웹 브라우저나 워드프로세서같은 User Process를 처리하는 Thread 도 있을 것이고, 일반적으로 발생하는 Kernel Process를 처리하는 Thread도 있을 것이다. 물론 Kernel Process를 처리하는 Kernel Thread는 운영체제단에서 daemon과 같은 형태로 지원이 된다. 리눅스에서 Thread에 관한 내용을 thread_struct에서 가지고 있다.
< /arch/x86/include/asm/processor.h : 밑에 Damn you 라는 주석이 인상적이다.>
주석도 달려있다시피 가장 밑단의 소스이기 때문에 cpu의 register를 건드리는 변수들이 많이 있다. 그런데 여기서 다루는 건 task_struct내에 있는 thread의 구조체인 것이고, 실제로 kernel_thread를 살펴보는 thread정보는 ptrace.h에 들어있다.
</arch/x86/include/asm/ptrace.h>
여기도 역시 cpu register들이 정의되어 있다. 이게 실제로 쓰이는 부분은 process.c라는 파일에 들어 있다.
일전에 linux에선 thread는 light weighted Process라는 말을 했었는데 그 말처럼 역시 thread의 생성에는 마지막에 do_fork(), 즉 child process를 생성하는 것과 마찬가지로 생성한다. 이와 같이 우리가 잘알고 있는 OS인 Windows, Mac OS, Linux는 Kernel Thread를 지원한다.
반면 사용자가 이 Process를 처리하는 thread,즉 User Thread를 사용하기 위해서는 말그대로 User level에서 사용할 수 있는 thread library 를 활용해야 한다. 가장 대표적인 library가 POSIX standard library인 Pthread이다. 말 그대로 POSIX Thread 라는 뜻인데 궁금한 사람은 이전 포스트를 참고하면 될 거 같다.
2013/02/21 - [About School] - [Study] POSIX
이밖에도 windows계열에서 사용할 수 있는 Win32 Thread나 Java Thread가 있다.
간단한 예제를 통해서 Pthread 사용법을 정리해보고자 한다. Process생성에도 몇가지 기본적인 함수들이 있었던 것처럼 Thread 생성에 있어서도 가장 기본적인 함수가 create, Join, Exit이다. Create는 말 그대로 thread를 생성하는 함수인데, 이외에도 return 값을 통해서 error checking을 할 수 있다. 가령 error가 발생했을 경우에는 -1을 return 하게 된다. Join은 Process 생성시 사용했던 함수 중에 wait과 유사한 함수이다. 그래서 thread 생성시 다른 thread가 종료될 때까지 기다리는 역할을 수행한다. exit은 말 그대로 calling state를 terminate 시키는 함수다.
자 그럼 간단한 예제를 만들어본다. 우선 pthread를 활용하기 위해서는 앞에서 언급한 것처럼 pthread.h를 포함시켜야 하며, 지금 보여주는 예제는 Thread의 생성과 Join이 제대로 되는지를 확인하는 것이다. 코드는 다음과 같다.
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <pthread.h> 6 7 void *thread_function(void *arg); 8 char message[] = "Test Thread"; 9 10 int main() 11 { 12 int num; 13 pthread_t test_thread; 14 void *thread_result; 15 16 num = pthread_create(&test_thread, NULL, thread_function, (void *)message); 17 18 if(num != 0){ 19 perror("Thread creation failed!"); 20 exit(EXIT_FAILURE); 21 } 22 23 printf("Waiting for thread to finish..\n"); 24 25 num = pthread_join(test_thread, &thread_result); 26 27 if(num != 0){ 28 perror("Thread Join Failed!"); 29 exit(EXIT_FAILURE); 30 } 31 32 printf("Thread joined, return value : %s\n", (char *)thread_result); 33 printf("Message is now %s\n", message); 34 exit(EXIT_SUCCESS); 35 } 36 37 void *thread_function(void *arg) 38 { 39 printf("thread_function executed. Argument is %s\n", (char *)arg); 40 sleep(3); 41 strcpy(message, "finish!"); 42 43 pthread_exit((void *)"Finished thread_function"); 44 }
위 코드의 동작을 살펴보자면 thread function이라는 함수를 생성하고 create를 통해서 호출하는 형식을 취하고 있다. 그러고 난 후에 test_thread를 또 join 시키고 있다. 만약 정상적으로 수행된다면 create에서 출력되는 message와 join했을 때의 message값, 나중에 빠져나왔을 때의 값이 전부 다를 것이다.
그럼 컴파일을 해야 되는데 지금 위 코드는 pthread를 사용하기 때문에 컴파일시에도 이에 대한 플래그를 세워야 한다. 결국 다음과 같이 컴파일하면 결과를 얻을 수 있다.
두번째는 thread function을 하나 삽입하고 main과 동시에 수행하게끔 하는 예제이다.
1 #include <stdio.h> 2 #include <pthread.h> 3 #include <stdlib.h> 4 5 void *thread_function(void *arg); 6 7 int thread_num = 1; 8 9 int main() 10 { 11 int num; 12 pthread_t test_thread; 13 void *thread_result; 14 int count = 0; 15 16 num = pthread_create(&test_thread, NULL, thread_function, NULL); 17 18 while(count++ < 20){ 19 if(thread_num == 1){ 20 printf("1"); 21 thread_num = 2; 22 } 23 else 24 sleep(1); 25 } 26 27 printf("\nWaiting for thread to finish...\n"); 28 num = pthread_join(test_thread, &thread_result); 29 printf("thread joined!\n"); 30 exit(EXIT_SUCCESS); 31 } 32 33 void *thread_function(void *arg) 34 { 35 int count = 0; 36 37 while(count++ < 20){ 38 if(thread_num == 2){ 39 printf("2"); 40 thread_num = 1; 41 } 42 else 43 sleep(1); 44 } 45 }
잘보면 thread_num이 1로 되어 있는 상태에서 새로운 thread를 생성하고 thread_num을 2로 바꾸었다. 이렇게 하면 thread_function 내에서 조건문이 반응하고 2를 출력하게 된다. 이 같은 과정이 반복하면 20번씩 1과 2를 출력하게 된다. 결과는 다음과 같다.
간단하게 pthread를 사용하는 방법에 대해 알아보았다. 뭐 조금더 궁금한 사람은 /usr/include/pthread.h 파일을 살펴보면 thread 사용시 쓰는 구조체나 함수의 틀을 확인해볼 수 있다..
'Study > OS' 카테고리의 다른 글
[Process] Exceptional Control (0) | 2014.08.28 |
---|---|
[Memory] Memory Consideration in OS (0) | 2013.11.26 |
[OS] Context Switch (0) | 2013.06.29 |
[Process] Inter Process Communication (IPC) (5) | 2013.06.21 |
[Process] Process Creation (0) | 2013.06.20 |
[Memory] Memory Addressing (2) | 2013.06.20 |
[Process] Process Scheduling (1) | 2013.06.20 |
- Total
- Today
- Yesterday
- 강화학습
- 파이썬
- Gan
- arduino
- 딥러닝
- PowerPoint
- End-To-End
- ColorStream
- Offline RL
- bias
- Kinect SDK
- Policy Gradient
- Windows Phone 7
- SketchFlow
- ai
- processing
- dynamic programming
- Distribution
- windows 8
- reward
- DepthStream
- Pipeline
- RL
- TensorFlow Lite
- Expression Blend 4
- Kinect
- Off-policy
- 한빛미디어
- Variance
- Kinect for windows
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |