쓰레드의 상태는 계속해서 변경된다. 입력 및 출력 연산을 시작하거나 종료하는 경우, 또는 새로운 쓰레드 생성에 의해서도 변경될 수 있다. 상황이나 운영체제 관리방법에 따라 쓰레드의 상태가 변경되므로 프로그래머가 상태를 직접적으로 컨트롤 하는것이 아니다.
그러나 경우에 따라서는 쓰레드의 상태를 프로그래머가 임의로 변경시켜야만 하는 경우도 있을 수 있다. 특정 쓰레드의 상태를 Blocked 상태로 만든다거나, Ready상태로 둔다거나 경우에 따라서 상태를 변경시키는것이 필요할 수 있다.
쓰레드의 상태변화
Windows에서는 상태가 변화하는 주체가 프로세스가 아니라 쓰레드이다.
1,2
쓰레드는 생성되면 Ready상태에 놓이게 된다. 이후 스케줄러에 의해서 선택될 경우 Running 상태가 되어 실제 실행이 된다. Ready상태에 놓이는 쓰레드는 여러개일 수 있지만, Running 상태 즉 현재 실행중인 쓰레드는 하나밖에 될 수 없다.
3.
실행중인 쓰레드에게 할당된 타임 슬라이스(Time Slice)가 모두 소비되어서, 다른 쓰레드에게 실행기회를 넘겨야 할 때, Running 상태에서 Ready상태로의 이동이 이뤄진다. Ready상태로 이동시켜야만 언제든지 다시 실행될 수 있기 때문에 Ready상태로 이동하는 것이 맞다.
4,5
Running 상태에 있는 쓰레드가 입,출력 연산을 하거나, Sleep함수가 호출될 경우 Blocked 상태로 이동하고 다른 쓰레드의 실행을 도모하게 된다. Block 상태가 끝나면 다시 Ready 상태로 돌아가서 실행을 기다린다.
Suspend & Resume
쓰레드의 상태 컨트롤
DWORD SuspendThread(
HANDLE hThread
);
Blocked 상태에 두고자 하는 쓰레드의 핸들을 인자로 전달한다.
DWORD ResumeThread(
HANDLE hThread
);
Ready 상태에 두고자 하는 쓰레드의 핸들을 인자로 전달한다.
쓰레드의 커널 오브젝트에는 SuspendThread 함수의 호출 빈도수를 기록하기 위한 서스펜드 카운트(Suspend Count)라 불리는 멤버가 존재한다. 현재 실행중인 쓰레드의 서스펜드 카운트는 0이다.
이 쓰레드 핸들을 인자로 SuspendThread 함수가 호출이 되면, 서스펜드 카운트는 1이되고 쓰레드는 Blocked 상태가 된다. 이 상태에서 SuspendThread함수를 한번더 호출하면 서스펜드 카운트는 2가된다. 즉 SuspendThread 함수는 서스펜드 카운트를 1증가시킨다. ResumeThread함수는 반대로 서스펜드 카운트를 하나 감소시키는 역할을 한다. 즉 위 상황에서는 ResumeThread함수를 두번 호출해야 서스펜드 카운트가 0이되고 Ready상태에 놓이게 된다.
SuspendThread 함수와 ResumeThread 함수의 반환값은 모두 변경되기 이전의 서스펜드 카운트를 반환한다.
CreateThread의 인자로 CREATE_SUSPENDED가 전달되면, 쓰레드는 생성되자 마자 서스펜드 카운트가 1이다. 즉 쓰레드가 생성되자 마자 Blocked상태가 되는 것이다.
쓰레드의 우선순위 컨트롤
프로세스는 쓰레드를 담는 그릇이다. Window에서는 프로세스가 아닌 프로세스 내부에서 동작하는 쓰레드가 우선순위를 갖는다.
쓰레드의 상대적 우선순위 Priority Meaning
THREAD_PRIORITY_LOWEST -2
THREAD_PRIORITY_BELOW_NORMAL -1
THREAD_PRIORITY_NORMAL 0(Default)
THREAD_PRIORITY_ABOVE_NORMAL +1
THREAD_PRIORITY_HIGHEST +2
쓰레드의 우선순위는 프로세스의 우선순위와 쓰레드의 우선순위 조합으로 결정된다.
예를 들어 우선순위가 NORMAL_PRIORITY_CLASS(9)인 프로세스 안에 두개의 쓰레드가 존재한다. 각각 쓰레드 우선순위가 THREAD_PRIORITY_LOWEST(-2), THREAD_PRIORITY_NORMAL(0)이라면각쓰레드의우선순위는7(9-2),9(9-0)으로결정된다.
즉 프로세스 우선순위에서 쓰레드 우선순위에 해당하는 값을 더하거나 빼면 쓰레드의 실질적인 우선순위가 나온다.
프로세스 내에서 생성되는 모든 쓰레드의 우선순위는 THREAD_PRIORITY_NORMAL이다. 즉 프로세스의 기존 우선순위를 그대로 수용하는 것이다. 이를 변경하거나 참조할때 다음 두 함수를 사용한다.
BOOL SetThreadPriority(
HANDLE hThread,
int nPriority
);
int GetThreadPriority(
HANDLE hThread
);
'Programming > Windows System Programming' 카테고리의 다른 글
유저 모드 동기화(Synchronization In User Mode) (0) | 2020.07.29 |
---|---|
쓰레드 동기화 (0) | 2020.07.28 |
쓰레드의 성격과 특성 (0) | 2020.07.25 |
Windows에서의 쓰레드 생성과 소멸 (0) | 2020.07.23 |
쓰레드 구현 모델에 따른 구분 (0) | 2020.07.22 |