데샤봇


IPC랑은 별개지만 중요



프로세스 핸들에는 커널 오브젝트 상태가 존재한다.

상태 : 리소스의 현재 상황을 알리기 위함


프로세스가 작동중이면

커널 오브젝트 상태 : Non-Signaled

작동중이 아니라면

커널 오브젝트 상태 : Signaled


그 밖에 다른 상태 정보들도 존재한다.


위의 예는 프로세스만을 대상으로 설명했지만 기타 리소스별로 나타내는 의미가 다른데 많고 번잡해도 중요한 것들이 존재



WailForSingleObject() 함수는 전달한 임의의 프로세스 커널 오브젝트 상태가 Signaled 상태로 변경되기를 기다리는 함수다.


함수에 커널 오브젝트 핸들을 전달하고, 얼마나 기다릴 것인지? 기다린다.



CPU 코어가 많아서 멀티프로세스 환경에서 연산을 분배해서 나눠가져야 하는 상황이 있는데, 이러한 멀티프로세스 환경에서 사용가능할 함수를 사용해


CPU 코어의 부담을 나눈다.



이런 식으로 진행하고자 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
        NonStopAdderManager.cpp
*/
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
int _tmain(int argc, TCHAR* argv[])
{
    STARTUPINFO si1 = { 0, };
    STARTUPINFO si2 = { 0, };
    PROCESS_INFORMATION pi1;
    PROCESS_INFORMATION pi2;
    DWORD return_val1;
    DWORD return_val2;
    TCHAR command1[] = _T("Branch1.exe 1 5");
    TCHAR command2[] = _T("Branch2.exe 6 10");
    DWORD sum = 0;
    si1.cb = sizeof(si1);
    si2.cb = sizeof(si2);
    CreateProcess(NULL,
        command1,
        NULL,
        NULL,
        TRUE,
        0,
        NULL,
        NULL,
        &si1,
        &pi1
    );  //CreateProcess 1
    CreateProcess(NULL,
        command2,
        NULL,
        NULL,
        TRUE,
        0,
        NULL,
        NULL,
        &si2,
        &pi2
    );  //CreateProcess 2
    CloseHandle(pi1.hThread);
    CloseHandle(pi2.hThread);
    //WaitForSingleObject(pi1.hProcess, INFINITE);
    //WaitForSingleObject(pi2.hProcess, INFINITE);
    GetExitCodeProcess(pi1.hProcess, &return_val1);
    GetExitCodeProcess(pi2.hProcess, &return_val2);
    if (return_val1 == -1 || return_val2 == -1)
        return -1//비정상적 종료
    sum += return_val1;
    sum += return_val2;
    _tprintf(_T("total : %d \n"), sum);
    CloseHandle(pi1.hProcess);
    CloseHandle(pi2.hProcess);
    return 0;
}
cs


44, 45 : WFS 함수


CreateProcess 1, CreateProcess 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
        PartAdder.cpp
*/
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
int _tmain(int argc, TCHAR* argv[])
{
    if (argc != 3)
        return -1;
    DWORD start = _ttoi(argv[1]);
    DWORD end = _ttoi(argv[2]);
    DWORD total = 0;
    for (DWORD i = start; i <= end; i++)
        total += i;
    return total;
}
cs



만약 주석을 해제하지 않는다면 결과로 518이 나온다.


각각의 return_val변수가 259를 담고 있는데, 오류코드인가? 값이 고정되어 있는 것을 보면 오류코드가 맞는 듯 한데...


이러면 만약 adder가 259를 리턴하면 어쩌려고 이런 값을 뱉는거지?


잘모르겠군


주석을 해제하면 정답이 잘 나온다.

'운영체제 > 윈도우 시스템' 카테고리의 다른 글

컴구세번째 함수호출  (0) 2019.10.08
프로세스간 통신(IPC)2  (0) 2019.10.01
프로세스간 통신  (0) 2019.09.26
커널 오브젝트, 핸들의 종속관계  (0) 2019.09.26
커널 오브젝트 오브젝트 핸들  (0) 2019.09.26



1 Program != 1 Process


1 Program == n Process


하나의 프로그램을 이루기 위해 n개의 프로세스가 서로 데이터 통신을 해야하는 경우가 종종 있다.


이 때, 프로세스간 통신이 원활히 이루어져야 좋은 프로그램이 될 것



프로세스의 메모리는 안정성을 이유로 OS에 의해 분리되어있다. (고립되어있다.)


그렇기 때문에 프로세스간 공유할 메모리 공간을 확보해야하는데, 그러한 공간을 OS가 또한 제공해준다.


이러한 기법을 Inner Process Communication, IPC라 부른다.


프로세스간 통신

프로세스간 데이터 송수신 -> 메모리 공유


-> 데이터를 순차적으로 보내는 것이 아니라, A프로세스가 공유가 가능한 어떠한 메모리 공간을 생성, B프로세스는 그곳에 보낼 데이터를 집어넣는다.

A프로세스는 생성한 메모리 공간을 확인, 데이터가 있으면 데이터를 받아온다.



메일슬롯


IPC 데이터 통신 기법의 하나. Receiver는 데이터를 받을 수 있는 우체통을 만들기 위해 함수를 호출한다. OS는 그러한 함수 호출을 통해 Receiver와 Sender가 접근 가능한 메모리 공간을 마련한다.


Receiver가 "서울 100번지"라는 이름의 주소를 설정해 OS에 요청하면, 주소를 알고 있는 Sender가 주소에 데이터를 붙여서 전송하면 OS가 그것을 보고 해당 주소에 보낸다.


핵심 함수는 우체통 생성, 전송, 송신의 3가지 함수다.(추가적으로 하나 더 있다.)


여기서 중요한 점은 이러한 방식의 기법이 단방향이라는 것이다. 


일반적으로 통신은 양방향이지만, 이러한 우체통의 송수신 방식은 단방향이기때문에 Sender는 데이터를 보낼수는 있지만, 받을수는 없다.


또한 n개의 Receiver가 동일한 주소의 우체통을 생성할수도 있다. 이 경우 Sender가 해당 주소로 데이터를 전송할 때 한번에 각각 Receiver가 데이터를 받을 수 있다. 


이를 브로드캐스팅이라고 한다.



Receiver


CreateMailSlot

우체통을 만든다


Sender


CreateFile

우체통과의 길을 뚫는다.


밑의 OX는 단방향 통신의 특성을 보여준다.


왜 송수신을 하는데 함수 이름이 File인가?


근본적으로 메일슬롯 방식은 메모리 공유다. 파일 기반으로 구현이 되어 있어서 기존 함수를 사용하는 것이다.


다른 의미로는 파일 기반으로 구현되어 있다는 것을 노출한 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
        MailReceiver.cpp
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define SLOT_NAME    _T("\\\\.\\mailslot\\mailbox")
int _tmain(int argc, LPTSTR argv[])
{
    HANDLE hMailSlot;  //mailslot 핸들
    TCHAR messageBox[50];
    DWORD bytesRead;  // number of bytes read
          /* mailslot 생성*/
    hMailSlot = CreateMailslot(SLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, NULL);
    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        _fputts(_T("Unable to create mailslot!\n"), stdout);
        return 1;
    }
    /* Message 수신*/
    _fputts(_T("******** Message ********\n"), stdout);
    while (1)
    {
        if (!ReadFile(hMailSlot, messageBox, sizeof(TCHAR) * 50&bytesRead, NULL))
        {
            _fputts(_T("Unable to read!"), stdout);
            CloseHandle(hMailSlot);
            return 1;
        }
        if (!_tcsncmp(messageBox, _T("exit"), 4))
        {
            _fputts(_T("Good Bye!"), stdout);
            break;
        }
        messageBox[bytesRead / sizeof(TCHAR)] = 0//NULL 문자 삽입
        _fputts(messageBox, stdout);
    }
    CloseHandle(hMailSlot);
    return 0;
}
cs


7 : .의 위치에는 컴퓨터 이름을 넣어야 한다. .의 의미는 나 자신을 의미한다. Receiver는 사용자 컴퓨터에서 실행하기 때문에 .밖에 올 수 없다. 나 자신의 위치에 데이터를 받아야지


14 : 두번째 인자는 버퍼 크기를 의미한다. 0은 허용최대치

세번째 인자는 데이터가 우체통에 들어올때까지 계속 기다릴것인지를 묻는 옵션이다. 이 경우 Blocked 상태가 되는 것


24 : ReadFile의 첫번째 인자는 슬롯을 지정하는 것이다. hMailSlot로 CreateMailSlot함수를 호출하면 슬롯이 생성되면서 슬롯의 핸들이 반환된다. 그 핸들을 넣어 Read의 대상(슬롯)을 지정한다

두번째 인자는 읽은 데이터를 저장할 버퍼를 의미한다

세번째 인자는 읽는 데이터의 최대 크기를 의미한다

네번째 인자는 실제로 읽은 데이터 크기를 얻기 위해 존재한다.

다섯번째 인자는 보류


38 : 커널오브젝트의 소멸을 돕기 위해 UC를 내리기 위한 CloseHandle 함수다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
        MailSender.cpp
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define SLOT_NAME _T("\\\\.\\mailslot\\mailbox")
int _tmain(int argc, LPTSTR argv[])
{
    HANDLE hMailSlot;  //mailslot 핸들
    TCHAR message[50];
    DWORD bytesWritten;  // number of bytes write
    hMailSlot = CreateFile(SLOT_NAME, GENERIC_WRITE, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        _fputts(_T("Unable to create mailslot!\n"), stdout);
        return 1;
    }
    while (1)
    {
        _fputts(_T("MY CMD>"), stdout);
        _fgetts(message, sizeof(message) / sizeof(TCHAR), stdin);
        if (!WriteFile(hMailSlot, message, _tcslen(message) * sizeof(TCHAR), &bytesWritten, NULL))
        {
            _fputts(_T("Unable to write!"), stdout);
            CloseHandle(hMailSlot);
            return 1;
        }
        if (!_tcscmp(message, _T("exit")))
        {
            _fputts(_T("Good Bye!"), stdout);
            break;
        }
    }
    CloseHandle(hMailSlot);
    return 0;
}
cs


7 : 같은 컴퓨터기때문에 .이 찍혀야한다. 이게 왜 있냐면 네트워크로 연결되어 있는 서로 다른 컴퓨터에서도 사용이 가능하다. 

근데, TCP/IP를 사용하는것이 일반적이다. 이거 잘 안씀


13 : 첫번째 인자는 연결 슬롯의 이름이다

두번째 인자는 Read인지, Write인지를 결정하는 옵션이다.

다섯번째 인자는 생성 방식을 의미한다. OPEN_EXISTING은 새로 만들것인지, 존재하는 것을 연결할 것인지 뭐 그런것

Sender의 CreateFile은 그 인자가 대체로 고정되어있는 편이다. 일단 읽고 넘어가라고함


24 : 첫번째 인자는 주소정보를 지정하는 것이다

두번째 인자는 전송 데이터를 담은 버퍼다

세번째 인자는 최대 전송 데이터 크기다

네번째 인자는 전송 결과를 의미한다.

다섯번째는 보류


36 : 클로즈핸들ㅇㅇ



결과 

왼쪽은 Sender

오른쪽은 Receiver


마치 소켓통신같군


추가할거더잇음 함수좀더봐야함

'운영체제 > 윈도우 시스템' 카테고리의 다른 글

프로세스간 통신(IPC)2  (0) 2019.10.01
Signaled Non-Signaled  (0) 2019.09.27
커널 오브젝트, 핸들의 종속관계  (0) 2019.09.26
커널 오브젝트 오브젝트 핸들  (0) 2019.09.26
프로세스, 스케줄러  (0) 2019.09.25




사용자에 의해 프로세스 A가 실행된다.

-> 프로세스 A의 부모 프로세스는 OS다


프로세스 A에 의해 프로세스 B가 실행된다.

-> 프로세스 B의 부모 프로세스는 A다.


프로세스 B에 의해 파일이 실행된다.

-> 파일의 부모 프로세스는 프로세스 B다.


프로세스는 실행될 때 프로세스, 프로세스 커널 오브젝트, 프로세스 핸들이 실행된다.


프로세스는 프로세스 핸들 테이블을 가지고 있다.(사진 참고)


프로세스 핸들 테이블에는 프로세스가 들고 있는 핸들 키, 그리고 핸들 대상이 존재한다.


프로세스 A

프로세스 핸들 번호는 운영체제로부터 부여받는다. 프로세스 A가 실행되면 프로세스 A의 핸들 테이블에 자신의 커널 오브젝트를 지정하는 핸들 값이 생성된다.


위 경우 핸들값은 3이다. 프로세스 A의 커널 오브젝트 UC(Usage Count)가 1로 올라갔다.


프로세스 B

프로세스 A로부터 생성된 프로세스 B도 생성과 동시에 커널 오브젝트와, 핸들 테이블, 운영체제로부터 생성된 핸들값이 핸들 테이블에 저장된다. 위 경우 값은 3이다.


또한, 프로세스 B의 커널 오브젝트에 접근할 수 있는 핸들값이 프로세스 B를 생성한 프로세스 A에도 리턴된다. 위 경우 값은 7이다.


즉, 프로세스 B의 커널 오브젝트 UC는 프로세스 B 자신의 핸들과, 프로세스 A의 핸들로 인해 2가 된다.






프로세스 B의 설명으로, 부모 프로세스도 핸들 테이블에 자식 프로세스의 커널 오브젝트 접근 핸들이 저장된다는 것을 알게 되었다.


프로세스 A 역시 부모 프로세스 OS가 존재하기 때문에, 프로세스 A 커널 오브젝트 UC는 2가 된다.


파일


파일은 프로세스가 아닌 단순 리소스이기 때문에 제어가 불가능하다. 즉 프로그램 코드가 없기 때문에 스스로 커널 오브젝트를 제어할 수 없다.


이 경우 파일의 커널 오브젝트는 생성이 되지만 그 커널 오브젝트에 접근이 가능한 것은 파일의 부모 프로세스인 프로세스 B다. 그렇기 때문에 위 경우의 파일 커널 오브젝트의 UC는 1이다.


정리로 인해, 핸들 테이블은 프로세스에 종속적이라는 사실을 알게 되었다.



만약 프로세스 B를 종료한다면, 프로세스 B를 종료해도 프로세스 B의 커널 오브젝트는 사라지지 않는다.


그 이유는 프로세스 A가 프로세스 B의 커널 오브젝트에 접근하는 핸들을 가지고 있기 때문이다.


레퍼런스 카운팅 방식과 비슷하게, 임의의 프로세스 커널 오브젝트에 접근하고 있는 핸들이 하나라도 있다면 커널 오브젝트는 사라지지 않는다.




라고 했는데...



1. 프로세스 A를 생성했을 때, 프로세스 핸들 테이블에 자기 자신을 가리키는 핸들이 정말 생성 되는가?


2. 자식 프로세스 B를 종료했을 때, 부모 프로세스 A는 자식 프로세스 B의 커널 오브젝트 핸들을 가지고 있을 필요가 있을까?


부모 프로세스가 자식 프로세스의 커널 오브젝트 핸들을 가지고 있어야 하는 이유


일반적인 코드에서, return 0;를 사용하는 의미는 프로그램을 정상 종료하겠다는 의미다. 


여기서 값 01-1 등은 해당 프로세스의 커널 오브젝트에 들어간다.


이때 부모 프로세스가 자식 프로세스의 실행에 밀접한 관련이 있다면 자식 프로세스의 동작 유무, 종료 유무는 상당히 중요한 부분이 있는데


만약 자식 프로세스가 비정상적 종료코드를 받거나 정상적 종료코드를 커널 오브젝트에 받은 채 프로세스와 커널 오브젝트를 동시에 소멸시켜 버린다면


부모 프로세스는 자식 프로세스가 정상적인 종료가 되었는지, 비정상적 종료가 되었는지 알 길이 없다.


그래서 임의의 프로세스 커널 오브젝트에 관심을 가지고 있는 프로세스가 하나라도 있으면 임의의 프로세스는 소멸되더라도 프로세스 커널 오브젝트는 사라지지 않는다.


ANSI함수와 Windows 시스템 함수


C표준인 ANSI함수를 실행하면 윈도우 환경에서 ANSI함수는 윈도우 시스템 함수를 호출한다. 마찬가지로, ANSI함수를 유닉스 환경에서 실행하면 유닉스 시스템 함수를 호출한다.


ANSI함수는 각각 OS의 시스템 함수를 랩핑한채 존재하는 것이다.


여기서 주의해야 할 점은 윈도우 시스템 함수를 랩핑되지 않은 함수이기 때문에 빠르다고 생각할 것이 아니라(물론 빠르긴 하지만)


윈도우 시스템 함수, 유닉스 시스템 함수들은 ANSI함수에 비해 제공하는 기능이 훨씬 많다는 측면에서 생각해야 한다.


프로세스 핸들 테이블은 자기 자신의 핸들값을 가지고 있을까?


사실 임의의 프로세스를 생성하더라도 자기 자신의 핸들값이 핸들 테이블에 들어가지는 않는다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
 
int _tmain(int argc, TCHAR* argv[])
{
    //우선순위를 변경하는 함수
    //GetCurrentProcess() 현재 프로세스의 핸들 정보를 가져오는 함수
    //HIGH_PRIORITY_CLASS 우선순위를 높이는 매크로
    SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
    while (1)
    {
        //Sleep()함수는 Blocked 상태로 변환된다. 우선순위를 포기하는 것
        //우선순위를 관찰하기 위해선 Ready 상태로 두어야 한다.
        for (DWORD i = 0; i < 10000; i++)
            for (DWORD i = 0; i < 10000; i++);    //Busy Waiting!!
        _fputts(_T("Operation2.exe \n"), stdout);
    }
    return 0;
}
 
cs


여기서 GetCurrentProcess()는 OS로부터 임의의 핸들 값을 부여받아 핸들 테이블에 집어넣은 값이 아니라. 고유한 값을 가지는 특정 상수다. 

(자기 자신을 호출하는 IP주소처럼)


즉 핸들 테이블의 내용물은 증가하지 않지만, 커널 오브젝트의 UC는 증가한다. 그냥 프로세스와 같이 들고있는 것이다.



STARTUPINFO si = { 0 };

생성 정보를 담는다


PROCESS_INFORMATION pi;

프로세스 정보를 담는다


핸들 정보는 프로세스 정보를 담은 pi에 들어간다.


커널 오브젝트는 종속적으로 여러 프로세스에 의해 접근이 가능하다


다른건 별거없다. 부모 프로세스가 자식 프로세스의 우선순위를 변경하는 예제다.



CloseHandle(pi.hProcess);


핸들을 끊는 함수다. 자식 프로세스 정보를 담고있는 변수 pi의 핸들을 닫겠다고 OS에 요청을 보내면 OS가 pi 커널 오브젝트의 UC를 1 내린다.



커널 오브젝트의 종속 관계

 

“커널 오브젝트는 Windows 운영체제에 종속적이다.”

 

‘종속’이라는 단어는 뜻이 상당히 넓다. 기본적으로 종속이라는 말은 독립적이지 못하다는 뜻이다.

 

예를 들어, 도서 대여점에 가면 많은 양의 도서가 있다.

 

이 도서들은 도서 대여점에 등록된 고객들만 대여할 수 있다.

 

그렇다면, 이 책들은 누구에게 종속적일까?

 

당연히 도서 대여점에 종속적이다.

 

도서 대여점에 있는 도서는 특정 고객에게 소유되는 물건이 아니다. 따라서 어느 누구라도 대여 관계가 깨끗하면 대여가 가능하다.

 

이를 위해, 도서 대여점에서는 도서를 소유하고 관리한다.

 

때문에, 고객은 임의로 도서를 폐기 할 수 없지만 대여점은 임의로 폐기 할 수 있다.

 

그렇다면, 커널 오브젝트가 Windows 운영체제(커널)에 종속적인 이유를 들겠다.

 

첫 째, 도서(커널 오브젝트)는 고객(프로세스)에 종속적이지 않고, 도서 대여점(운영체제)에 종속적인 관계로, 도서의 폐기(커널 오브젝트의 소멸)은 도서 대여점(운영체제)에 의해 결정된다.

 

둘 째, 도서(커널 오브젝트) 는 고객(프로세스)에게 종속되는 것이 아니므로, 여러 고객(여러 프로세스)에 의해 대여(접근) 이 가능하다.



'운영체제 > 윈도우 시스템' 카테고리의 다른 글

Signaled Non-Signaled  (0) 2019.09.27
프로세스간 통신  (0) 2019.09.26
커널 오브젝트 오브젝트 핸들  (0) 2019.09.26
프로세스, 스케줄러  (0) 2019.09.25
컴퓨터를 디자인하자  (0) 2019.09.23



커널

-> 기존에 커널 = OS였지만 시대가 변하면서 점차 의미가 분리되었다.


커널 오브젝트

커널에 의해 관리되는 리소스 정보를 담고 있는 데이터 블록

-> 윈도우에 의해 생성되고 소멸되는 리소스를 관리하기 위한 데이터 블록을 커널 오브젝트라고 한다.


-> 커널과 커널 오브젝트는 다르다. 커널 오브젝트는 프로세스와 밀접한 관련이 있다.


또한 파이프 커널 오브젝트, 프로세스 커널 오브젝트, 쓰레드 커널 오브젝트는 각각 다르게 디자인되어있다.



사용자가 프로세스를 실행하면 프로세스만 실행되는 것이 아니라 os로 인해 프로세스에 대한 커널 오브젝트가 생성되고 커널 오브젝트는 프로세스 정보를 담고있고 관리하기 위한 커널 오브젝트가 생성된다.


또한 커널 오브젝트를 관리하기 위한 커널 오브젝트 관리 구조체도 생성된다. 커널 오브젝트 관리 구조체로 인해 커널 오브젝트가 생성된다.



예)

프로세스를 생성하면 프로세스 커널 오브젝트가 생성된다.


만약 사용자가 이 프로세스의 연산 우선순위를 높이고 싶다고 생각하고 실제로 우선순위를 높이기 위해서는 커널 오브젝트에 접근하여야 하는데, 커널 오브젝트는 임의의 접근이 불가능하다.


이 때 커널 오브젝트를 다루기 위해 필요한 것이 핸들로, 사용자가 os에 프로세스를 실행하도록 요청하면 os는 프로세스와, 프로세스 커널 오브젝트와, 프로세스 커널 오브젝트 핸들(프로세스 핸들)을 생성한다.


핸들은 os에 의해 특정 숫자로 넘버링된 이름을 가지고 있는데(실제로 int형 정수로 구성되어 있다.) 이를 이용하여 커널 오브젝트에 접근할 수 있게 된다.



Operation2.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
 
int _tmain(int argc, TCHAR* argv[])
{
    //우선순위를 변경하는 함수
    //GetCurrentProcess() 현재 프로세스의 핸들 정보를 가져오는 함수
    //HIGH_PRIORITY_CLASS 우선순위를 높이는 매크로
    SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
    while (1)
    {
        //Sleep()함수는 Blocked 상태로 변환된다. 우선순위를 포기하는 것
        //우선순위를 관찰하기 위해선 Ready 상태로 두어야 한다.
        for (DWORD i = 0; i < 10000; i++)
            for (DWORD i = 0; i < 10000; i++);    //Busy Waiting!!
        _fputts(_T("Operation2.exe \n"), stdout);
    }
    return 0;
}
cs


Operation1.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
 
int _tmain(int argc, TCHAR* argv[])
{
    STARTUPINFO si = { 0, };
    PROCESS_INFORMATION pi;
    si.cb = sizeof(si);
    TCHAR command[] = _T("branch.exe");
    CreateProcess(NULL, command, NULLNULL, TRUE, 0NULLNULL&si, &pi);
    while (1)
    {
        for (DWORD i = 0; i < 10000; i++)
            for (DWORD i = 0; i < 10000; i++);
        _fputts(_T("Operation1.exe \n"), stdout);
    }
    return 0;
}
cs


싱글코어 기반의 출력결과

않이


듀얼이상에선 순서대로 나온다.

프로세스란?


일반인 : 실행중인 프로그램


개발자 : 메모리 구조(OS에 의해 할당되는 메인 메모리의 리소스 뿐 아니라 가상 메모리의 리소스까지 포함), 실행중인 프로그램에 독립적인 레지스터 Set, etc


요즘 프로세스는 컨텍스트 스위칭을 피하기 위해 레지스터 Set을 여러개 만들어 스위칭에 의한 오버헤드를 피하고 있다.




스케줄러 : 운영체제에서 제공해주는 소프트웨어 장치(혹은 블럭)


공평한 스케줄링 알고리즘도 큰 이슈중 하나다



Running 상태 : CPU에 의해 실행중인 상태

Ready 상태 : 스케줄러에 의해 선택되길 기다리는 상태, 실행 준비는 다 끝난 상태

Blocked 상태 : 연산중에서 ALU(CPU)에 의존적인 연산이 있고, I/O연산처럼 의존적이지 않은 연산이 있다. Running상태는 CPU 연산이 진행되는 중이고, Blocked 상태는 현재 I/O 연산중인 프로세스를 뜻한다.

I/O연산이 끝나면 Blocked 상태가 끝나고 Ready 상태로 변한다.




컨텍스트 스위칭은 일반적으로 멀티태스킹 환경에서 1초에도 수십번씩 한다.

+ Recent posts