뮤텍스 질문입니다..
글쓴이: 소맛라면 / 작성시간: 금, 2005/07/29 - 2:13오후
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<pthread.h> 6 #include<semaphore.h> 7 8 void *thread_function(void *arg); 9 pthread_mutex_t work_mutex; 10 11 #define WORK_SIZE 1024 12 char work_area[WORK_SIZE]; 13 int time_to_exit = 0; 14 15 int main(){ 16 int res; 17 pthread_t a_thread; 18 void *thread_result; 19 res = pthread_mutex_init(&work_mutex,NULL); 20 if(res != 0){ 21 perror("Mutex initialization failed"); 22 exit(EXIT_FAILURE); 23 } 24 res = pthread_create(&a_thread, NULL, thread_function,NULL); 25 if(res != 0){ 26 perror("Thread creation failed"); 27 exit(EXIT_FAILURE); 28 } 29 pthread_mutex_lock(&work_mutex); 30 printf("Input some text. Enter 'end' to finish\n"); 31 while(!time_to_exit){ 32 fgets(work_area, WORK_SIZE, stdin); 33 printf("1") 34 pthread_mutex_unlock(&work_mutex); 35 while(1){ 36 pthread_mutex_lock(&work_mutex); 37 if(work_area[0] != '\0'){ 38 pthread_mutex_unlock(&work_mutex); 39 sleep(1); 40 } 41 else{ 42 break; 43 } 44 } 45 } 46 pthread_mutex_unlock(&work_mutex); 47 printf("\nWainting for thread to finish...\n"); 48 res = pthread_join(a_thread, &thread_result); 49 if(res != 0){ 50 perror("Thread join failed"); 51 exit(EXIT_FAILURE); 52 } 53 printf("Thread join \n"); 54 pthread_mutex_destroy(&work_mutex); 55 exit(EXIT_SUCCESS); 56 } 57 58 void *thread_function(void *arg) 59 { 60 printf("2"); 61 sleep(1); 62 pthread_mutex_lock(&work_mutex); 63 while(strncmp("end",work_area, 3) != 0){ 64 printf("You input %d characters\n", strlen(work_area) -1); 65 work_area[0] = '\0'; 66 pthread_mutex_unlock(&work_mutex); 67 sleep(1); 68 pthread_mutex_lock(&work_mutex); 69 while(work_area[0] == '\0'){ 70 pthread_mutex_unlock(&work_mutex); 71 sleep(1); 72 pthread_mutex_lock(&work_mutex); 73 } 74 } 75 76 time_to_exit = 1; 77 work_area[0] = '\0'; 78 pthread_mutex_unlock(&work_mutex); 79 pthread_exit(0); 80 }
[root@localhost chapter12]# ./thread4 Input some text. Enter 'end' to finish asdf 21You input 4 characters end 1 Wainting for thread to finish... Thread join [root@localhost chapter12]#
뮤텍스에 대해 잠시 보고 있습니다.
의문나는 점이 있어서 이렇게 질문을 하내요.
실행화면을 보면 숫자 1이 2뒤에 출력되는것을 볼수 있습니다.
소스를아무리 봐도 이해가 가지 않습니다
숫자 1이 먼저 출력 되야 하지 않을까요?
fgets()로 문자열을 입력 받은 후에 바로 출력 해줬는데
어찌 숫자2가 먼저 출력 될까요???
Forums:
[code:1] 60 pthread_mutex_lock&#
쓰레드 사이에서 어떤 것이 우선권을 가질지는 스케쥴러 마음입니다.여기
쓰레드 사이에서 어떤 것이 우선권을 가질지는 스케쥴러 마음입니다.
여기서는 당연히 쓰레드가 먼저 생성되었기 때문에 2가 먼저 출력되는게 당연한것 같습니다. 메인 함수에서는 쓰레드 생성후에 몇가지 작업을 하는 반면, 쓰레드에서는 생성되자 마자 2를 출력하게 되어있으니...
mutex 보다는 condition variable을 써야 원하는 제어구조를 얻을 수 있습니다.
정상입니다.* 왜 1이 먼저 출력되어야 한다고 생각하십니까?
정상입니다.
* 왜 1이 먼저 출력되어야 한다고 생각하십니까?
제 생각은 이렇습니다.공유변수 초기화 -> 뮤택스 초기화 -
제 생각은 이렇습니다.
공유변수 초기화 -> 뮤택스 초기화 -> 쓰래드 생성 이 때부터 쓰레드가 2개가 되는것이죠..
메인과 새로운 쓰레드..
제 생각에도 2가 먼저 나오는것이 맞기는 맞습니다..
왜냐면 main 에서 새로운 쓰레드 생성후 fgets()함수를 호출할때까지 2개의
쓰레드 같이 실행되니까요(사실은 그렇지 않지만..)
main 이 fgets()를 실행하기 전에 숫자 2를 찍어 줘야 제가 생각하는 논리에
맞는것 같습니다..
하지만 보는바와 같이 fgets()실행 후에 숫자 2가 먼저 찍히니 이상하다는
것이죠
fgets()함수를 호출하기 전에 이미 숫자 2가 찍혀 있지만
보이지 않고 있다가. fgets()후에 보이는 것인가요???
머릿속이 복잡하군요...;;
무엇을 위해 사는가..
[quote]...fgets()함수를 호출하기 전에 이미 숫자 2
예.
이 문제는 아주 빈번하게 회자되는 주제군요. FAQ수준..
* 일단 concurrent programming을 수행(개발/디버깅등)할 때는 buffered io를 사용하지 않을것을 권고합니다.
* 아래를 실행해보면 되겠습니다.
실험 1) 그냥 출력함
#include <stdio.h>
main()
{
printf("1");
sleep(3); // 엥 ? 3초동안 1도 안나오네....
printf("2");
} // 읔, 프로그램 종료되니까 나오네..
실험 2) printf()의 끝부분에 \n을 추가함
#include <stdio.h>
main()
{
printf("1\n"); // 음 ... \n의 효과라...!
sleep(3);
printf("2");
}
실험 3) stdout의 라이브러리의 버퍼를 0으로 함=>버퍼링 안함
#include <stdio.h>
main()
{
setvbuf (stdout, NULL, _IONBF, 0);etvbuf (stdout, NULL, _IONBF, 0); // 버퍼를 0으로...
printf("1"); // \n 없음
sleep(3);
printf("2");
} // 이경우 printf() == write()와 거의 동급으로 사용됨, 나은점은 %d등 포맷팅이 자유롭다는..
실험 4) printf()후 매번 강제로 버퍼를 비워줌(강제출력) =>버퍼링 안함
#include <stdio.h>
main()
{
printf("1");
fflush(stdout);
sleep(3);
printf("2");
fflush(stdout);
} // 좀 귀찮나서리... 키보드치기가... 또한 atomic하지도 않고...
* 질문자는 1번과 같은 유형으로 수행해서 그러합니다.
* 운영체제 스케쥴러에 의해 다수 프로세스/쓰레드가 실제 printf()를 실행한 순서대로 출력하기 위해서는 buffered-io를 사용해서는 안됩니다.
* 저는 그래서 관습처럼 unbuffered-io를 일단 기본 IO로 사용할 것을 권고합니다.
* 효율등의 문제로 버퍼링을 하는것이 필요하다면 이는 만들어서 쓰는게 좋겠다는...
* 어쨌거나 저는 write()를 가장 선호합니다. 상위 버퍼링은 자작으로...
쿵~아 ...오타가.... 실험3의 올바른 코드는 아래와 같습니다.
쿵~
아 ...오타가.... 실험3의 올바른 코드는 아래와 같습니다.
감사합니다...실험해보니..그렇군요...이러한 문제가 있었다니..
감사합니다...
실험해보니..그렇군요...
이러한 문제가 있었다니...
감사합니다.
손님님...
무엇을 위해 사는가..
댓글 달기