프로그램언어/C/C++
Posix Thread Example
쫑환이
2012. 3. 24. 23:41
1 Posix Thread Example
작성자: mwyun(멍)
쓰레드 생성후 자동 종료하는 간단한 예제입니다.
2 pthread 예제1
2.1 pthread1.c 소스코드
#include <stdio.h> #include <string.h> #include <pthread.h> pthread_t threads[5]; int done[5]; void *thread_main(void *); int main(void) { int i; int rc; int status; printf("pid=%d\n", getpid()); for (i = 0; i < 5; i++) { done[i] = 0; pthread_create(&threads[i], NULL, &thread_main, (void *)i); printf("%d, %d\n", i, threads[i]); } for (i = 4; i >= 0; i--) { done[i] = 1; rc = pthread_join(threads[i], (void **)&status); if (rc == 0) { printf("Completed join with thread %d status= %d\n",i, status); } else { printf("ERROR; return code from pthread_join() is %d, thread %d\n", rc, i); return -1; } } return 0; } void *thread_main(void *arg) { int i; double result=0.0; printf("therad: %d, %d\n", (int)arg, getpid()); while (!done[(int)arg]) { for (i=0; i < 1000000; i++) { result = result + (double)random(); } printf("thread: %d, result = %e\n", (int)arg, result); } pthread_exit((void *) 0); }
2.2 pthread1 실행결과
[mwyun@ns mwyun]$ gcc -o pthread1 pthread1.c -lpthread [mwyun@ns mwyun]$ ./pthread1 pid=2790 therad: 0, 2790 0, 1082346288 therad: 1, 2790 1, 1090738992 therad: 2, 2790 2, 1099131696 therad: 3, 2790 3, 1116957488 therad: 4, 2790 4, 1125350192 thread: 2, result = 1.073082e+15 thread: 1, result = 1.074421e+15 thread: 4, result = 1.073731e+15 Completed join with thread 4 status= 0 thread: 0, result = 1.073430e+15 thread: 3, result = 1.074102e+15 Completed join with thread 3 status= 0 thread: 2, result = 2.146727e+15 Completed join with thread 2 status= 0 thread: 1, result = 2.147847e+15 Completed join with thread 1 status= 0 thread: 0, result = 2.148343e+15 Completed join with thread 0 status= 0 [mwyun@ns mwyun]$
생성된 쓰레드가 정상적으로 동작하고 pthread_exit함수를 통해서 0값을 리턴하고 종료하였으므로 pthread_join함수에서 status값 0이 출력된다.
3 pthread 예제2
쓰레드 생성후 강제로 종료시키는 간단한 예제입니다.
3.1 pthread2.c 소스코드
#include <stdio.h> #include <string.h> #include <pthread.h> pthread_t threads[5]; int done[5]; void *thread_main(void *); int main(void) { int i; int rc; int status; printf("pid=%d\n", getpid()); for (i = 0; i < 5; i++) { done[i] = 0; pthread_create(&threads[i], NULL, &thread_main, (void *)i); printf("%d, %d\n", i, threads[i]); } for (i = 4; i >= 0; i--) { rc = pthread_cancel(threads[i]); // 강제종료 if (rc == 0) { // 자동종료 rc = pthread_join(threads[i], (void **)&status); if (rc == 0) { printf("Completed join with thread %d status= %d\n",i, status); } else { printf("ERROR; return code from pthread_join() is %d, thread %d\n", rc, i); return -1; } } } return 0; } void *thread_main(void *arg) { int i; double result=0.0; printf("therad: %d, %d\n", (int)arg, getpid()); while (!done[(int)arg]) { for (i=0; i < 1000000; i++) { result = result + (double)random(); } printf("thread: %d, result = %e\n", (int)arg, result); } pthread_exit((void *) 0); }
3.2 pthread2 실행결과
[mwyun@ns mwyun]$ gcc -o pthread2 pthread2.c -lpthread [mwyun@ns mwyun]$ ./pthread2 pid=2845 therad: 0, 2845 0, 1082346288 therad: 1, 2845 1, 1090738992 therad: 2, 2845 2, 1099131696 therad: 3, 2845 3, 1116957488 therad: 4, 2845 4, 1125350192 thread: 3, result = 1.073353e+15 thread: 4, result = 1.074336e+15 thread: 0, result = 1.073328e+15 Completed join with thread 4 status= -1 thread: 1, result = 1.074552e+15 thread: 2, result = 1.073090e+15 thread: 3, result = 2.147247e+15 Completed join with thread 3 status= -1 thread: 0, result = 2.147519e+15 thread: 1, result = 2.147391e+15 thread: 2, result = 2.147080e+15 Completed join with thread 2 status= -1 thread: 0, result = 3.221195e+15 thread: 1, result = 3.221001e+15 Completed join with thread 1 status= -1 thread: 0, result = 4.295871e+15 Completed join with thread 0 status= -1 [mwyun@ns mwyun]$
pthread_cancel 함수를 사용하여 강제적으로 종료하였으므로 pthread_join함수에서 status값 -1이 출력된다.
4 pthread 예제3
쓰레드 생성후 쓰레드를 분리시키는 간단한 첫번째 예제입니다.
4.1 pthread3.c 소스코드
#include <stdio.h> #include <string.h> #include <pthread.h> pthread_t threads[5]; int done[5]; void *thread_main(void *); int main(void) { int i; int rc; int status; printf("pid=%d\n", getpid()); for (i = 0; i < 5; i++) { done[i] = 0; pthread_create(&threads[i], NULL, &thread_main, (void *)i); printf("%d, %d\n", i, threads[i]); } for (i = 4; i >= 0; i--) { done[i] = 1; rc = pthread_join(threads[i], (void **)&status); /* detach thead에서는 사용할 필요 없다. */ if (rc == 0) { printf("Completed join with thread %d status= %d\n",i, status); } else { printf("ERROR; return code from pthread_join() is %d, thread %d\n", rc, i); return -1; } } return 0; } void *thread_main(void *arg) { int i; double result=0.0; pthread_detach(pthread_self()); /* 쓰레드 분리 */ printf("therad: %d, %d\n", (int)arg, getpid()); while (!done[(int)arg]) { for (i=0; i < 1000000; i++) { result = result + (double)random(); } printf("thread: %d, result = %e\n", (int)arg, result); } pthread_exit((void *) 0); }
4.2 pthread3 실행결과
[mwyun@ns mwyun]$ gcc -o pthread3 pthread3.c -lpthread [mwyun@ns mwyun]$ ./pthread3 pid=2949 therad: 0, 2949 0, 1082346288 therad: 1, 2949 1, 1090738992 therad: 2, 2949 2, 1099131696 therad: 3, 2949 3, 1116957488 therad: 4, 2949 4, 1125350192 ERROR; return code from pthread_join() is 22, thread 4 [mwyun@ns mwyun]$
결과를 보면 에러가 발생하는 것을 볼 수 있다.
참조사이트의 Thread Management > Joining Threads를 보면
It is impossible to join a detached thread (discussed next)
이라고 나온다.
즉, detached thread된 것은 join이 불가능하므로 pthread_join함수를 사용할 필요가 없다.
참고로 pthread_joinc은 waitpid와 비교될 수 있다.
5 pthread 예제4
쓰레드 생성후 쓰레드를 분리시키는 간단한 두번째 예제입니다.
pthread3.c에서 pthread_joinc에 관련된 코드를 삭제하였습니다.
5.1 pthread4 소스코드
#include <stdio.h> #include <string.h> #include <pthread.h> pthread_t threads[5]; int done[5]; void *thread_main(void *); int main(void) { int i; int rc; int status; printf("pid=%d\n", getpid()); for (i = 0; i < 5; i++) { done[i] = 0; pthread_create(&threads[i], NULL, &thread_main, (void *)i); printf("%d, %d\n", i, threads[i]); } for (i = 4; i >= 0; i--) { done[i] = 1; } /* 쓰레드들이 실행하고 종료할 때 까지 잠시 기다린다. sleep을 주지 않으면 메인이 종료되므로 자동으로 생성된 쓰레드도 강제종료되므로 올바른 테스트 진행되지 않아서 이다. */ sleep(5); return 0; } void *thread_main(void *arg) { int i; double result=0.0; pthread_detach(pthread_self()); printf("therad: %d, %d\n", (int)arg, getpid()); while (!done[(int)arg]) { for (i=0; i < 1000000; i++) { result = result + (double)random(); } printf("thread: %d, result = %e\n", (int)arg, result); } printf("thread %d terminated....\n", (int)arg); pthread_exit((void *) 0); }
5.2 pthread4 실행결과
[mwyun@ns mwyun]$ gcc -o pthread4 pthread4.c -lpthread [mwyun@ns mwyun]$ ./pthread4 pid=3140 therad: 0, 3140 0, 1082346288 therad: 1, 3140 1, 1090738992 therad: 2, 3140 2, 1099131696 therad: 3, 3140 3, 1116957488 therad: 4, 3140 4, 1125350192 thread: 0, result = 1.074314e+15 thread 0 terminated.... thread: 4, result = 1.073499e+15 thread 4 terminated.... thread: 1, result = 1.073339e+15 thread 1 terminated.... thread: 2, result = 1.074428e+15 thread 2 terminated.... thread: 3, result = 1.073145e+15 thread 3 terminated.... [mwyun@ns mwyun]$