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까지 실행함.