diff --git a/lec14/report14.md b/lec14/report14.md new file mode 100644 index 0000000000000000000000000000000000000000..d88bb088311433e2189ddb0b96ec9dedc2a5f3ef --- /dev/null +++ b/lec14/report14.md @@ -0,0 +1,123 @@ +# Lecture 14 + +## 1. Thread (2) + +이전 실습에서 threadtest.c가 실행이 되지 않았음 + +- threadtest.c : void fn_s() + ``` + void fn_s() + { + static int a = 0; + printf("== %d %d ==\n",a++, bbb++); + } + ``` + - fn_s의 I/O에서 buffer가 flush 되지 않아 발생했던 문제. + 즉 100번 실행이 끝나면 한번에 I/O가 일어나서 쓰레드의 진행결과를 볼 수 없었음 + - 따라서 printf 실행 직후 \n을 통해 buffer를 flush해 해결 +- ```\n``` = flush? + - 줄바꿈 문자가 I/O flush가 되는 이유 : 즉 bash는 line-by-line으로 동작한다는 의미. + - 즉 줄바꿈이 일어날 때 마다 I/O가 flush 된다는 것임 + +## 2. Buffer 제어 + +1. stdbuf + - 표준 I/O 스트림의 버퍼를 수정 + ``` + stdbuf --output=0 a.out + ``` + - a.out의 stdout의 버퍼를 0으로 설정 + - \n 없이 입력이 들어올 때마다 flush가 일어남 +2. setvbuf + - 프로그램 내에서 버퍼를 직접 설정하는 방법 + ``` + #include <stdio.h> + int setvbuf(FILE *stream, char *buf, int mode, size_t size); + ``` + - 사용예시 + ``` + void fn_s() + { + static int a = 0; + setvbuf(stdout, NULL, _IOFBF, 10); + printf("== %.2d %.2d ==",a++, bbb++); + } + ``` + - _IONBF: NULL BUFFERING : 버퍼 미사용 (stdbuf --output=0과 의미가 같음) + - _IOLBF: LINE BUFFERING : 줄 버퍼링 사용 -> 줄바꿈 문자를 만나면 flush + - _IOFBF: FULL BUFFERING : size를 버퍼로 사용 + +## 3. Mutex + +- Thread끼리는 같은 메모리 공유 -> 여러 쓰레드가 같은 메모리를 수정하려하면 오류가 발생할 수 있음 +- 자원을 독점적으로 한 쓰레드가 사용할 수 있게 하는 방법으로 Mutex가 있음(Mutual exclusion) +- mutextest.c - fn_s() + ``` + void fn_s() + { + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static int a = 0; + printf("<= %d %d =>",a, bbb); + pthread_mutex_lock(&mutex); + a++; bbb++; + pthread_mutex_unlock(&mutex); + } + ``` +- mutextest.c - main() + ``` + int main() + { + pthread_t thread1; + pthread_t thread2; + pthread_t thread3; + int result1, result2, result3; + + pthread_create(&thread1, NULL, run, NULL ); + pthread_create(&thread2, NULL, run, NULL ); + pthread_create(&thread3, NULL, run, NULL ); + pthread_join(thread1, (void **) &result1); + pthread_join(thread2, (void **) &result2); + pthread_join(thread3, (void **) &result3); + printf("\nThread return %d at the end\n", result1); + } + ``` +- 실행결과 (1000번 반복실행, 쓰레드 3개) + ``` + Hello world of POSIX threads.-547121344 + <= 0 0 => + Hello world of POSIX threads.-555600128 + <= 1 1 => + <= 2 2 => + <= 3 3 => + <= 4 4 => + <= 5 5 => + <= 6 6 => + <= 7 7 => + <= 8 8 => + <= 9 9 => + <= 10 10 => + <= 11 11 => + <= 12 12 => + <= 13 13 => + <= 1 1 => + <= 15 15 => + <= 16 16 => + <= 17 17 => + <= 14 14 => + Hello world of POSIX threads.-563992832 + <= 19 19 => + <= 18 18 => + <= 21 21 => + <= 22 22 => + <= 23 23 => + <= 24 24 => + ... + <= 2994 2994 => + <= 2995 2995 => + <= 2996 2996 => + <= 2997 2997 => + <= 2998 2998 => + <= 2999 2999 => + ``` + - 여러 쓰레드간 작업시 a와 bbb의 값이 정상적으로 올라감 + - 쓰레드 1이 0~999, 쓰레드2가 1000~1999, 쓰레드3이 2000~2999까지 실행함.