0강 Win32 작업자 스레드 동기화 9:33~
DWORD WINAPI ThreadFunction(LPVOID pParam)
{
puts("*** Begin Thread ****");
for (int i = 0; i < 5; ++i)
{
printf("[Worker thread] %d\n", i);
::Sleep(1);
}
//스레드가 끝나기 전에 이벤트를 세트한다.
puts("종료 이벤트 세트 전");
//이 함수를 호출하면 _tmain() 함수의
//WaitForSingleObject() 함수가 반환한다!
::SetEvent((HANDLE)pParam);
puts("종료 이벤트 세트 후");
puts("**** End Thread ****");
return 0;
}for (int i = 0; i < 5; i++)
{
printf("[Main thread] %d\n", i);
//i값이 3이면 이벤트가 세트되기를 무한정 기다린다!
if (i == 3 &&
::WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0)
{
puts("종료 이벤트를 감지했습니다!");
::CloseHandle(hEvent);
hEvent = NULL;
}
}3일 때 worker 스레드가 실행되는 조건문 하에서
Main함수가 2일 때도 반환되고 0일 때도 반환됩니다.
말씀해주신대로 3일 때 반환되는 경우도 있지만 보장되지 않고 빈번하게 아래 케이스처럼 반환되는 경우가 있습니다.(디버그 모드, 릴리즈 모드 모두에서)
이는 무슨 이유 때문인지 궁금합니다.
case1
[Main thread] 0
[Main thread] 1
[Main thread] 2
*** Begin Thread ****
[Worker thread] 0
[Main thread] 3
[Worker thread] 1
[Worker thread] 2
[Worker thread] 3
[Worker thread] 4
종료 이벤트 세트 전
종료 이벤트 세트 후
**** End Thread ****
종료 이벤트를 감지했습니다!
[Main thread] 4
case2
[Main thread] 0
*** Begin Thread ****
[Main thread] 1
[Main thread] 2
[Worker thread] 0
[Main thread] 3
[Worker thread] 1
[Worker thread] 2
[Worker thread] 3
[Worker thread] 4
종료 이벤트 세트 전
종료 이벤트 세트 후
**** End Thread ****
종료 이벤트를 감지했습니다!
[Main thread] 4
답변 2
0
기존 예제에서 코드를 변경하지 않은 것이라면 다음과 같은 생각을 할 수 있습니다.
메인 스레드에서 i값이 3이 되고 WaitForSingleObject() 함수가 호출되는 순간은 앞서 작업자 스레드를 생성하고 실행하는 반복문 이후 입니다. 그러나 스케줄링 문제로 생성한 작업자 스레드부가 실행되기 전에 메인 스레드에서 i값이 3이 될 수 있습니다.
스레드를 생성하고 실행시켰다 해서 즉시 실행으로 이어지지는 않습니다. 생성된 작업자 스레드가 스케줄러에 의해 선택되고 CPU자원을 할당 받아야 실제로 연산이 시작 됩니다. 작업자 스레드 생성 및 요청 코드가 실행되는 메인 스레드는 작업자 스레드 코드가 실행되기 전에 i 값이 3이 될 수 있습니다.
메인 스레드에서 i값이 3이 되기 전에 작업자 스레드 중 일부가 실행 상태에 진입하고 심지어 메인 스레드가 WaitForSingleObject() 함수를 호출하기도 전에 이벤트를 세트하고 종료 될 수 있습니다. 물론 이를 방지하기 위해 Sleep() 함수를 호출해 대략 5ms 이상 지연이 발생하도록 유도 했지만 CPU가 어떤 순서로 스레드를 스캐줄링 할지는 알 수 없습니다. 이 지점부터 '우연'이라는 개념이 생겨납니다.
지금까지 설명한 것들과 별개로 어떤 경우라 하더라도 메인 스레드에서 i값이 4가 되는 경우는 작업자 스레드가 이벤트를 세트한 이후가 될 수 밖에 없습니다.
참고하시기 바랍니다. :)
recv, send 리턴값 질문
0
77
2
스타,워크와 같은 디스창 (Disconnected)도 비정상 종료에 대응하는 시스템으로 봐야할까요?
0
96
2
수업과 관련해서 읽어볼 만한 책 있나요?
0
111
1
서버가 끊어버리는것에 대한 질문
0
121
2
TCP 의도적 장애 테스트 질문
0
159
2
shutdown()을 호출하는 이유
0
165
1
프로토콜이 적용된 파일 송신 서버에서 send, recv 질문 있습니다!
0
153
2
"파일 송신 서버 제작" 강의 질문입니다!
0
151
2
대표적인 장애 유현 2
0
131
2
대표적인 TCP 장애 유현
0
161
2
이벤트 기반 파일 입출력과 callback 기반 파일 입출력이 네트워크에도 쓰이는 기법인가요?
0
120
2
개발환경 질문이 있습니다.
0
137
1
TCP/IP vs UDP , 멀티 스레드에서의 병목 현상에 대한 질문이 있습니다!
0
221
2
메모리 관련 문제로 질문드립니다.
0
187
2
테스트 환경 질문드립니다!
0
168
2
ThreadAcceptLoop 의 우아한(?) 종료에 대해 질문드립니다.
0
419
2
하트비트 시 서버에서의 연결 종료
0
451
2
강사님 질문 드립니다.
0
249
1
소켓 입/출력 설계 정리
0
450
1
멀티스레드 기반 서버 관련 질문..!
0
412
2
빅 엔디언과 리틀 엔디언
0
378
2
TIME_WAIT 관련 문의드립니다.
0
226
1
강사님 강의자료 인쇄용으로 부탁드립니다.
0
288
1
bind 함수 관련 궁금증
0
357
2





