'전체 글'에 해당되는 글 16건

1. 메모리 영역

 

메모리 영역 중 Stack 에 대해 설명하시오

 프로그램에서 사용되는 임시 메모리 영역입니다. 

 유효기간 함수의 시작부터 종료되는 순간까지 입니다.

 메모리 영역 중 가장 끝부분부터 메모리를 할당하기 때문에 메모리가 늘어날 수록 주소는 낮아진다 특징이 있습니다.

 지역변수, 매개변수, 리턴 값 등이 이 영역을 사용합니다.

 

메모리 영역 중 Heap 에 대해 설명하시오

 프로그래머가 관리하는 메모리 영역입니다.

 유효기간 사용자가 원할 때 할당되고 소멸됩니다.

 동적할당되는 메모리가 이 영역을 사용합니다.

 

메모리 영역 중 Data 에 대해 설명하시오

 프로그램이 실행되는 내내 유지되는 데이터를 저장하는 메모리 영역입니다.

 유효기간 프로그램이 시작되는 순간부터 종료되는 순간까지 입니다.

 전역변수, 정적변수가 이 영역을 사용합니다.

 

메모리 영역 중 Code 에 대해 설명하시오

 코드 자체를 구성하는 메모리 영역입니다. 

 유효기간 프로그램이 시작되는 순간부터 종료되는 순간까지 입니다.

 함수, 제어문, 키워드 등이 이 영역을 사용합니다.

 

 

2. exe 파일 생성과정

 

프로그램 실행 파일을 생성하는 순서를 말하시오

 코드 -> 전처리기 -> 컴파일러 -> 어셈블러 -> 링킹 -> exe파일 생성 입니다.

 

코드 단계에 대해 설명하시오

 프로그래머가 고급언어를 이용하여 코드를 작성하는 단계입니다. 

 

고급언어란 무엇입니까

 사람이 이해할 수 있도록 만든 언어, C언어, C++언어 등을 말합니다. 

 

전처리기 단계에 대해 설명하시오

 컴파일링 이전에 실행되는 단계로 컴파일러가 작업하기 좋도록 소스를 재구성해주는 단계입니다.

 include, define 등의 명령이 전처리기 단계에 해당됩니다.

 

컴파일링 단계에 대해 설명하시오

 컴파일러가 고급언어에서 저급언어로 번역하는 단계입니다. 

 

저급언어란 무엇입니까

 앞서 언급한 고급언어와 기계어 사이에 위치하는 언어입니다. 

 

어셈블링 단계에 대해 설명하시오

 어셈블러가 저급언어에서 기계어로 번역하는 단계입니다. 

 

기계어란 무엇입니까

 컴퓨터가 이해할 수 있는 언어, 이진수처럼 불 꺼짐과 들어옴 두 가지로 구성된 언어입니다.

 

링킹 단계에 대해 설명하시오

 obj 파일, 시동코드, 라이브러리를 연결하는 단계입니다.

 

obj 파일이란? 

 프로그래머가 작성한 소스코드를 말합니다.

 

시동코드?

 프로그램, 운영체제 사이의 인터페이스 역할을 수행하는 코드입니다.

 운영체제마다 프로그램을 처리하는 방식이 다리기 때문에 이를 중재하는 역할을 수행합니다.

 

라이브러리 코드?

 사용할 명렁어들에 대한 대한 정의가 있는 코드입니다.  

 전처리기 단계에서 사용할 라이브러리를 포함시킨 후 소스 코드에서 이 명령어들을 사용합니다.

 

exe 파일 생성 단계에 대해 설명하시오

 링킹으로 묵여진 파일을 exe파일이라고 합니다. 프로그램을 실행시키는 파일입니다.

 

'언어 > C++' 카테고리의 다른 글

질문형식 6. 상속의 다형성  (0) 2020.02.03
질문형식 5. 클래스의 상속  (0) 2020.02.03
질문형식 4. Class 기본  (0) 2020.02.03
질문형식 3. C++ 함수  (0) 2020.02.03
질문형식 2.C와 C++ 비교  (0) 2020.02.03
블로그 이미지

연한그린커리

,

시스템 프로그래밍

 

1장 컴퓨터 구조에 대한 첫 번째 이야기

 1 시스템 프로그래밍의 이해와 접근

시스템 프로그래밍이란?

 시스템 프로그램

  컴퓨터 시스템을 동작시키는 프로그램

  시스템 프로그램이란 하드웨어를 사용할 수 있도록 도와주는 프로그램이라고도 할 수 있다.

  컴퓨터를 동작시키기 위한 프로그램에는 Window, UNIX와 같은 운영체제들이 있다.

  시스템 프로그램으로 프로그램을 개발하는 것을 시스템 프로그래밍이라고 한다.

 

 

 2 컴퓨터 하드웨어의 구성

  CPU (Centeral Precessing Unit) : 중앙처리장치, 컴퓨터의 머리

  정의 : 나중에 자세히, 컴퓨터 프로그램 실행에서 핵심적 역하릉ㄹ 담당, 연산을 담당

 

  메인 메모리(Main Memroy) RAM

  정의 : 컴파일이 완료된 프로그램 코드가 올라가서 실행되는 영역이다.

  목적 : 프로그램 실행을 위해 존재하는 메모리이다.

 

 입 출력 버스(Input/Output Bus) : 고속도로

 정의 : 컴퓨터를 구성하는 구성요소 사이에서 데이터를 주고 받기 위해 사용되는 경로이다.

 목적 : 컴퓨터 구송 요소 사이 데이터를 주고 받기 위해 사용된다(통로 역할로)

 특징 : 주고받는 데이터의 종류와 역할에 따라 버스가 구분된다. (어드레스, 데이터, 컨트롤)

        구분되는 버스의 역할에 주의하자

 

버스 시스템 : 데이터를 이동하는 데 있어서 사용되는 전송 경로

데이터 버스 : 데이터를 이동하기 위한 버스

어드레스 버스 : 주소값을 이동하기 위해 필요한 버스

컨트롤 버스 : 사인을 주고받는 용도로 사용되는 버스 (사인? 데이터가 오고 가는 구분이 필요)

 

 

3 CPU에 대한 이해

ALU(Arithmetic Logic Unit)

 정의 : CPU에서 실제 연산을 담당하는 블록이다.

 목적 : 기본적인 연산(산술 연산, 논리 연산)을 담당한다.

 

컨트롤 유닛(Control Unit)

 정의 : 명령어를 해석하는 영역이다.

 목적 : CPU가 처리할 명렁어를 해석하는 역할을 담당한다.

 

레지스터 (Register Set)

 정의 : CPU 내부에서 임시 데이터를 저장하는 작은 메모리 공간이다.

 목적 : CPU 내부에서 임시적으로 데이터를 저장하기 위해서 레지스터를 사용한다.

 

버스 인터페이스(Bus Interface)

 정의 : I/O 버스와 CPU(하드, 그래픽 카드 등에도 필요하긴 함)를 연결시키는 인터페이스 장치

 목적 : CPUI/O 버스 사이 통신이 가능하게 하는 장치이다.

        I/O 버스의 통신방식을 알고 있으므로 CPU와의 데이터 전송이 가능하게 하는 것이다.

 

클럭 신호(Clock Pulse)

정의 : 클럭 발생기에 의해 발생되는 신호이다.

목적 : 클럭 신호에 맞춰 CPU가 작동된다. 

특징 : CPU의 구성요소는 아니다.

         하지만 CPU 구성요소에 제공되어야 하는 신호로 중요한 의미를 지닌다.

        가장 느린 장치의 장단에 맞춰 일한다.

 

 

 

4 프로그램의 실행 과정

 

단계 1 전처리기에 의한 치환 작업

 소스코드를 적절히 변경하는 작업

 

단계 2 컴파일러에 의한 번역

 컴파일러에 의 해 어셈블리 코드로 번역되는 단계

 어셈블리코드란 CPU에게 일을 시키기위한 명령어들로 만들어진 프로그램 코드이다.

 

단계 3 어셈블러에 의한 바이너리 코드 생성

어셈블러 어셈블리 코드를 CPU가 이해할 수 있는 바이너리 코드로 바꾸어주는 프로그램

 

단계 4 ㄹ잉커에 의한 연결과 결합

 

프로그램 실행 3단계

Fetch : 메모리 상에 존재하는 ㅁ여령어를 CPU로 가져오는 작업이다.

 

Decode : CPU로 가져다놓은 명령어를 해석하는 단계이다.

 

Execution : 해석된 명령어를 CPU가 실행하는 단계이다.

 

여기까지 공부하면 exe파일 생성과정과 프로그램 실행 3단계를 이어서 설명할 줄 알아야한다.

exe파일 생성과정을 통해 만들어진 바이너리로 이루어진 코드가 램에 올라감.

Fetch 과정을 통해 램에 있는 코드가 CPU(레지스터)에 임시 저장됨

Decode 과정을 통해 컨트롤 유닛이 레지스터에 올라간 코드를 해석함.

Execution 과정을 통해 해석된 코드를 ALU가 실행시킴.

 

이런식으로 말이야.

 

 

 

 

 

 

 

 

 

 

4장 컴퓨터 구조에 대한 두 번째 이야기

 1 컴퓨터 구조의 접근 방법

 

RISC vs CISC

명령어의 복잡도의 차이가 기준이지

CISC : Complex Instruction Set Computer : 복잡한 명령어 체계를 가지는 컴퓨터

명령어의 수가 많다. 따라서 명령어의 길이가 일정하지 않아 이를 처리하는 과정 역시 제각각이다.

 

 :간단한 명령어 체계를 가지는 컴퓨터

 

 

전체 명령어중 주로 사용하는 명령어가 10%밖에 되지 않는 데소 착안한 구조이다.

자주 사용하지 않는 90%이ㅣ상의 명령어를 위해 CPU 복잡하게 디자인하는 것보다 명령어 수를 줄이고 길이를 일정하게 디자인하는 효율적이라고 판단하여 탄생한 .

명령어의 길이가동일하여 명령어를 처리하는 과정이 일정화되어있으므로 이점이 있다.

 

3 Direct 모드와 Indirect모드 (Direct Addressing, Indirect Addressing)

 

레지스터 디자인 방법의 문제점.

하나의 명령어에 여러 정보 (명령어, 레지스터 정보, 연산할 수 등)을 담다보니 표현하는 데이터 크기에 제한이 따른다는 문제가 발생할 수 있다. 레지스터의 수나 연산할 수의 범위

 

Direct addressing mode

우리가 지금까지 언급한 메모리 접근방법을 Direct 모드라고 한다. 램의 주소에 값을 직접 넣어 레지스터로 값을 로드하는 방식이다.

이 방법을 통해서는 메모리의 모든 영역에 대한 접근이 불가능하다. 왜냐? 할당된 비트 수 안에서 표현 가능한 범위의 메모리 영역만 접근 가능하기 때문이다. 무슨말이야

 

Indirect addressing mode

Direct 모드가 가진 단점을 해결하기 위해 등장.

램의 주소에 주소값을 넣어 해당 주소에 접근, 참조한 값을 레지스터로 로드하는 방식이다.

주소값의 범위가 넓다면.. 레지스터를 참조하여 해당 레지스터에 들어있는 값을 주소값으로 사용하는 방법을 쓰면 더 넓은 주소값을 사용할 수 있다.

 

5장 프로세스의 생성과 소멸

 

1 프로세스의 이해

프로세스

 정의 : 실행 중에 있는 프로그램이다.

 

2 프로세스의 스케줄링과 상태 변화

스케줄링

 정의 : 프로세스의CPU 할당 순서 및 방법을 결정 짓는 일을 말한다.

         ? 동시에 여러 프로세스를 실행시켜야 하지만 CPU는 하나이므로 한 순간에 하나의 프로그램만 실행 가능하다. CPU가 여러 개의 프로세스를 번갈아 가면서 실행한다면 사용자는 동시에 여러 프로그램을 실행시키는 것처럼 느끼게 된다. 멀티 프로세스는 이처럼 여러 개의 프로세스들이 CPU할당 시간을 나누기 때문에 가능한 것이다.

 

스케줄링 알고리즘

 정의 : 스케줄링에 사용되는 알고리즘이다. 프로세스의 CPU 할당 순서 및 방법을 결정지을 때 사용하는 알고리즘이인 것이다.

 

스케쥴러 : 스케줄링 알고리즘을 적용하여 실제로 프로세스를 관리하는 운영체제 요소를 말한다. (소프트웨어이다)

 

프로세스의 상태 변화

 

프로세스 생성 : 프로세스는 생성과 동시에 Ready 상태로 들어간다.

Ready 상태에 이쓴 프로세스는 CPU에 의해 실행되기를 희망하는 상태이다.

(프로세스가 실행되지는 않고있으나 스케줄러에의해 선택되어 당장이라도 실행 가능한 상태)

 

Ready 상태에 있는 프로세스는 스케줄러에 의해 관리되는 프로세스이다.

스케줄러가 스케줄링 알고리즘을 기반으로 우선순위가 높은 프로세스를 선정하면 해당 프로세스는 Running 상태가 되어 실행된다.

 

프로세스들은 생성 시 중요도에 따라 우선순위가 매겨진다.

 

Running 상태에서는 프로세스에 따라 ready가 될 수도 blocked가 될 수도 있다.

 프로세스가 입출력을 실행한다면 blocked 상태가되고, 아직 일이 안끝났는데 다른 우선순위 높은 프로세스가 등장한다면 잠시 그 프로세스를 실행하고 바로 다시 실행 가능하도록 ready상태에서 잠시 대기할 수도 있는 것이다.

 

 

Blocked 상태 : 실행 중인 프로세스기 실행을 멈추는 상태, 스케줄러에 의 해 선택될 수 없는 상태이다 (ready와의 차이점 둘 다 프로세스가 실행되지 않는 상태임)

(프로세스가 실행되지 않고 있으며 스케줄러에 의해 선택될 수 없는 상태 : 따라서 입 출력이 완료된 프로세스는 ready상태를 거쳐 running 상태로 변화한다.)

일반적으로 데이터 입출력과 관련된 일을 하는 경우 이러한 상태가 된다. 프로그램 실행의 상당 시간을 데이터 입출력에 소모하고 스케쥴러는 이러한 비 우선적인 일을 수행하고 있는 프로세스는 Blocked 상태로 만들고, Ready에 있는 프로세스 중 우선순위 높은 프로세스를 Running 상태로 변경한다.

 

 

 

 

 

3 컨텍스트 스위칭(Context Switching)

멀티 프로세스 환경에서 프로세스를 교체함으로써 한번에 여러 개의 프로세스를 동시에 실행시키는 것처럼 보인다는 장점을 봤다. 하지만단점또한 존재한다. 실행중인 프로세스를 변경하는 일은 시스템 부하를 일으킨다는 사실이다. “CPU 내에 존재하는 레지스터들은 현재 실항 중에 있는 프로세스 관련 데이터들로 채워진다.” 프로세스를 교체하려면 레지스터 역시 교체해줘야하는 번거로움이 있다는 것이다. , 프로세스 교체가 일어나면 레지스터에 있는 데이터는 RAM으로,  RAM에 있는 데이터(실행될 프로세스와 관련)는 레지스터로 옮겨진다. 이러한 작업을 컨텍스트 스위칭이라고 한다. “실행되는 프로ㅓ세스의 변경과정에서 발생하는 컨텍스트 스위칭은 시스템에 많은 부담을 준다레지스터 개수가 많은 시스템일수록 프로세스별로 관리되야아할 데이터 종류가 많을수록 이러한 부담은 커진다. 우리는 멀티 프로세스 운영체제의 단점이 컨텍스트 스위칭에 의한 부담이다라고 할 수 있겠다.

 

 

4 프로세스의 생성

 CreateProcess 함수를 통해 프로세스를 생성. 함수를 호출하는 프로세스를 부모 프로세스, 함수에 의해 호출된 프로세스를 자식 프로세스라고 함.

 

이후 생성과 소멸 등 사용방법에 대한 설명은 Pass했다.

 

 

6장 커널 오브젝트와 오브젝트 핸들

 1 커널 오브젝트에 대한 이해

ㄹ커널 : 컴퓨터를 운옇나는 데 있어서 중심이 되는 운영체제 핵심 부분이다. 일반적으로 커널이라는 용어와 운영체제라는 용어는 같은 의미로 사용된다.

 

커널 오브젝트 : 커널에서 관리하는 중용한 정보를 담아둔 데이터 블록이다.

Window 운영체제는 프로세스, 쓰레드 혹은 파일과 같은 리소스들을 원활히 관리하ㅏ기 위해 필요한 정보를 저장해야 한다. 이때 데이터를 저장하는  메모리 블록을 가리켜 커널 오브젝트라고 한다.

 

중요한 정보? 프로세스 정보를 관리하는 구조체 등( 운영체제가 프로세스들의 상태정보와 우선순위 등을 알고있어야 프로세스 상태를 관리할 수 있다), 프로세스 뿐만 아니라 프로그램 흐름을 구성하는 쓰레드를 생성할 때에도 IPC를 위해 사요되는 파ㅇ이프나 멤일 슬롯을 생성할 때에도 커널 오브젝트를 생성해서 필요한 정보를 채우기도 한다. 파일을 생성시에도 커널오브젝트가 생성된다.

 

커널 오브젝트는 프로그래머가 직접 조작할 수 없다. 시스템 함수 호출에 의해 간접적으로 조작하는 것이다. 실제 조작은 Window 운영체제가 수행한다.

안정성을 위해서이다. 프로세스를 관리하는 정보인 커널 오브젝트에 직접적인 조작이 이루어진다면 시스템 안정성이 떨어질 수 있기 때문이다.

커널 오브젝트 핸들 : 커널 오브젝트에 할당되는 숫자이다. 시스템 함수로 프로세스의 우선순위 등을 간접 조작하고자 할 때 핸들을  전달하는 방법을 사용한다.

 

주의점 함수가 호출되어 실행되는 중간에는 절대로 CPU의 할당 시간을 다른 프로세스에게 넘겨주면 안된다. 함수호출이 완료되지 않고 넘어가기 때문

 

 

 

 

2. 커널 오브젝트와 핸들의 종속 관계

커널 오브젝트는 Windows 운영체제에 종속적이다? 커널 오브젝트는 프로세스에 종속적인 것이 아니라 운영체제에 종속적인 관계로커널 오브젝트의 소멸 시점은 운영체제에 의해 결정된다. 추가로 커널 오브젝트의 생성 역시 운영체제가 관리한다 (사용하는 함수에서 프로세스 생성하면 커널 오브젝트도 생성되어 프로세스가 생성하는 것처럼 보이는 것 뿐이다)

 

커널 오브젝트는 프로세스에 종속적인 것이 아니라 운영 체제에 종속적인 관계이다. 따라서 여러프로세스들은 커널 오브젝트에 간접적으로 접근할 수 있다. ( 커널 오브젝트는 여러 프록세스에 의해 접근 가능해)

 

-       커널 오브젝트 공유 예시. 부모 프로세스가 자식 프로세스의 커널 오브젝트에 접근하여 그 자식 프로세스의 우선순위를 낮춘다. ( 자식 프로세스의 커널 오브젝트에 여러 프로세스가 접근)

l  커널 오브젝트는 운영체제에 종속적. 따라서 하나의 커널 오브젝트에 여러 프로세스가 접근할 수 있으며, 프로세스가 소멸된다고 해서 해당 프로세스의 커널 오브젝트가 자동으로 소멸되는 것이 아니다.

핸들은 운영체제에 종속적이지 않고 프로세스에 종속적이다.

프로세스 핸들 : 프로세스 커널의 오브젝트를 가리키기(구분짓기)위 한 것

프로세스 ID는 프로세스 자체를 구분짓기 위한 것

종료코드 : return 문에 의해 반환되는 값처럼  제대료 종료가 되었는지, 혹은 특정 문제가 있어서 종료가 안되었는지 알리기 위해 사용하는 코드를 말한다. 프로세스의 종료코드는 해당 프로세스의 커널 오브젝트에 저장된다. 자식 프로세스의 종료코드는 자식 프로세스의 커널 오브젝트에 저장된다. (만약 자식 프로세스가 종료되면서 자식 프로세스의 커널 오브젝트도 동시에 소멸된다면부모 프로세스는 자식 프로세스의 종료코드를 얻을 수 있는 방법이 없다. 따라서 프로세스의 종료와 커널 오브젝트의 소멸은 동시에 이루어질 수 없는 것이다.)

 

Window 운영체제는 커널 오브젝트를 참조하는 대상이 하나도 없을 때 소멸시킨다. (레퍼런스 카운트 방식인 것이다.

 

 

7장 프로세스간 통신(IPC) 1

1. 프로세스간 통신 IPC의 의미

IPC : Inter Process Communication 프로세스 사이의 통신이라는 뜻이다. 즉 둘 이상의 프로세스가 데이터를 주고받는 행위이다.

 

모든 운영체제들은 프로세스가 자신에게 할당된 메모리 공간 이외의 영역에 접근하는 것을 허용하지 않는다.(안전성을 이유로) -> IPC를 위해서는 프로세스 외 다른 무언가가 필요하다.

 

2. 메일슬롯 방식의 IPC

 

메일슬롯방식 : 메일 슬롯이라는 우체통을 이용하여 프로세스간 데이터를 송수신한다.

데이터를 수신하는 프ㅗ로세스 Receiver가 멩리 슬롯을 생성한다.

 

특징

 할다된 주소를 기반을 통신하므로 네트워크만 연결되어 있따면 서로 관계 없는 프로세스 사이에서도 통신이 가능하다.

단방향 통신이다 ( 쌍방향으로 이용하기 위해서는 각각 메일슬롯 생성이 필요하다)

브로드캐스팅 방식의 통신을 지원한다.

 

3. 커널 오브젝트의 상태

커널 오브젝트는 두 가지 상태를 지닌다. 리소스에 특정 상황이 발생되었음을 알리기 위한 용도로 사용된다.

Signaled 상태 (신호를 받은 상태) 프로세스가 종료되면 Window 운영체제에 의해 자동으로 Signaled 상태가 된다.

Non_Signaled 상태 (신호를 받지 않는 상태) : 프로세스가 생성되면 Non_Signaled 상태에 놓이고 프로세스가 종료되면 Singnaled 상태로 변경된다.

 즉 프로세스가 실행중인지 여부를 알 수 있는 것이다.

상태가 존재하는 이유? 

 커널 오브젝트의 상태는 리소스에 특정 상황이 발생함을 알려주기 위함이다.

최초에 커널 오브젝트가 생성되면 커널 오브젝트 상태는 Non_signaled. 종료되면 signale.

 

프로세스를 기준으로프로세스가 non_signaled 상랭라면 프로세스가 실행중이라는 것이다.

커널 오브젝트가 생성되면 자동으로 non_singed 상태가 된다 (실행중이라는것이지) 즉 커널 오브젝트 디폴트 상태는 non_signaled이다. 프로세스가 생성된 당시는 실행중일 것이기 때문이다.

 

WaitForSingleObject 함수 (프로세스가 현재 실행중인지 있음)

함수를 통해 자식 프로세스가 signaed(실행종료)상태라면 함수는 바로리턴

Non_signled(실행중)이라면 함수는 블로킹상태가 된다(블로킹?)

함수는 커널의 상태를 확인하는 기능도 있으나… signaled(실행중)상태가 되기를 기다리는 기능이 크다.

 

 

 

 

 

 

 

 

 

 

 

8장 프로세스간 통신(IPC) 2

2. 파이프 방식의 IPC

이름 없는 파이프 Anonymous Pipe

 단방향 통신방식이다.

 파이프를 통해서 생성된 핸들을 기반으로 통신하기에 프로세스 사이 관계가 있어야한다.

 

 

이름 있는 파이프 Named Pipe

 주소 정보가 있어 관계없는 프로세스들 사이에서도 통신이 가능하며 양방향 통신을 지원한다.

 메일슬롯과 유사하다. 차이점은 브로드캐스트 방식을 지원하지 않고 양방향 통신을 지원한다는 점이다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

9장 스케줄링 알고리즘과 우선순위

1. 프로세스의 스케줄링( Scheduling)

 

RTOS Real time OS

 OS vs RTOS

응답속도 : RTOS의 응답속도가 일반 OS보다 빠르다. 사용하는 목적이 구체적이고 제한적이다 보니 단순하게 디자인 되었기 때문이다. 즉 가벼워서 더 빠른 것이다.

 

OS : d범용적인 사용을 위해 디자인

RTOS : 사용하는 영역이 제한되어 있다.

 

Hard RTOS vs Soft RTOS

 

Hard RTOS : 데드라인을 중요시한다.일정 시간 안에 반드시 처리해야 하며 시간이 지난 후 결과 값은 정확해도 소용이 없는 경우 사용한다. (군사장비나 비행기)

 

 

Soft RTOS

 시간 안에 처리하면 좋지만 그러지 못하더라도 약간의 시간이 경과한 후의 값도 인정한다.

 

 

 

 

 

 

 

Preemptive OS vs Non_Preemptive OS  (선점형 OS vs 비선점형 OS)

 

프로세스의 실행을 다른 프로세스로 넘기는 방식에 따라서 선점형 OS와 비선점형 OS를 구분한다.

비선점형 OS

현재 실행 중인 프로세스보다 높은 우선순위의 프로세스가 4등장한다고 해서 실행 대상을 바로 변경하지 않는다. 현재 실행중인 프로세스가 명시적으로 CPU를 양보하거나, 블로킹 상태에 놓일 때까지 기다린다.

문제점 : Interactive한 프로그램 구현 시 프ㅍ로그래머 의존도가 높아지는 문제점이 발생할 수 있다. 프로그래머의 프로그램이 CPU를 독차지 하지 않도록 신경 써서 ㅍ ㅡ로그래밍 해야한다.

 

선점형 OS

 실행중인 프로세스보다 높은 우선순위의 프로세스가 등장하면 스케줄러에 의한 실행순서 조징이 가해지는 OS이다. 따라서 비교적 스케줄러가 하는 일이 많다는 특징이 있다.

이러한 특징은 멀티 프로세스 기반 OS에 적합하다. 스케줄러에 의해 실행순서가 조정되는 것이므로 프로그래머의 의존도가 낮기 때문이다.

오늘날 대부분의 OS는 선점형 OS이다.

 

우선순위 스케줄링 알고리즘

 우선순위 스케줄링 알고리즘이란 각각의 프로세스마다 우선순위를 부여해서 우선순위가 높은 프로세스를 먼저 실행시키는 방식이다.

 

라운드 로빈 스케줄링 알고리즘

 우선순위가 동일한 프로세스들이 있는 경우라면?

 이러한 경우 형평성을 위해 정해진 시간 간격만큼 실행하고 우서ㅓㄴ순위가 동일한 다른 프로세스에게 CPU할당을 넘겨주는 방식이다. 타임 슬라이스를 기준으로 CPU 할당을 넘긴다.

 

퀸텀 or Time Slice : 실행의 최소 단위 시간 간격이다.

 

정리하자면 Window는 우선순위 기반과 라운드 로빈 기반 알고리즘을 혼용하여 선점형 운영체제의 특성을 나타내도록 디자인된 운영체제이다.!!!!!!

이러한 Window 운영체제에서 스케줄러가 동작하는 시점은

1. 매 타임  슬라이스마다 동작 (동일한 우선순위의 프로세스가 있다면 타임 슬라이스 기준으로 프로세스를 교체해아야 한다.

 

2. 프로세스가 생성 및 소멸될 때 동작 ( 새로운 프로세스가 등장하거나 없어지면 우선순위를 비교해줘야한다.

 

3. 실행중인 프로세스가 블로킹 상태에 놓일 때 동작 ( 실행할 프로세스를 찾기 위해 동작)

 

Priority Inversion

 

 

 

 

 

 

10장 컴퓨터 구조에 대한 세 번째 이야기

1. 절차적 함수 호출(Procedure Call) 지원 CPU 모델

 

스택 프레임 : 함수 호출 과정에서 할당되는 메모리 블록을 말한다.

                     메모리 구조적 특징이 스택과 동일하다. (가장 먼저 쌓인 메모리가 가장 나중에 반환된다.

                     스택 구조처럼 메모리가 쌓이고 함수 호출이 완료되면 해당 함수에서 쌓였던                       스택 프레임 메모리는 모두 반환되어 더 이상 접근할 수 없게 된다.

 

Sp 레지스터 (Stack Pointer)

목적 : 스택 프레임의 현재 위치를 저장하는 레지스터이다.

함수가 종료될 때 얼마만큼 반환할지 sp레지스터만으로는 모르기 때문에 프레임 포인터 레지스터에게 데이터를 전달받아야한다.

 스택 프레임에 데이터를 쌓으려면 스택의 어느 위치까지 데이터를 저장했는지 기억해야한다. (스택은 쌓아올라지는 구조이므로) 이를 위해 CPU내에 sp라는 이름의 레지스터가 존재한다.

 

프레임 포인터 레지스터 (Frame Pointer)

 

함수가 새로 호출되면 sp 레지스터가 가리키는 주소를 fp 레지스터에 담는다.

함수가 반환되면 sp 레지스터는 fp 레지스터에 기록된 위치로 돌아가면 현재 위치로 갈 수 있다.

 

함수가 중첩된다면 fp레지스터에 기록된 주소를 잃어버리게 되므로…. 덮어쓰기전에 stackfp 레지스텅의 주소를 저장한다. (stack에 함수간 경계로 fp 레지스터의 이전값이 생성되는 것이다 최산값은 fp 레지스터 자체가 가지고 있고)

 

 

 

 

 2. 함수 호출 인자의 전달과 PUSH  & POP 명령어 디자인

함수 호출 : 입력에 대한 출력이 반환값으로 존재하면 함수 호출이라고 한다.

프로시저 호출 : 출력에 해당하는 반환값 없이 모듈화해 놓은 서브루틴의 실행을 위한 호출임

 

함수가 호출되면

 1. 현재 fp에 저장된 주소 정보를 스택에 쌓는다.

 2. sp의 값을 fp에 저장한다.

 

3. 함수 호출에 의한 실행의 이동

Pc ( program count) 레지스터

 명령어를 순차적으로 fetch하기 위해 Code 영역에서 현재 실행되는 명령어가 있는 주소를 저장하는 레지스터이다. Fetch 연산이 일어날 때마다 자동으로 pc값이 증가한다. Pc 레지스터를 조작하면 절차지향을 거스를 수 있어..

 

 

Instruction Regisdter

명령어를 가져오기 위해서 사용되는 레지스터이다. 함수 호출 시 pc값을 저장하는 역할이다(함수종료 시 돌아갈 값을 백업). 덮어 써지는 경우는 stack에 보관한다.

 

코드 영역 : 프로그램이 동작하기 위한 프로그램 코드가 올라가는 위치이다. Fetch 단계에서 명령어를 가져오는 위치는 프로그램 코드가 존재하는 코드 영역이다. , 이진화된 명령어들이 Fetch 가 이루어지면 RAM의 메모리 영역 중 Code 영역에 올라오는 것이다.

 

4. 함수 호출 규약

함수 호출 규약(Calling Convention)

 함수 호출 시 인자를 전달하는 방식과 스택 프레임을 반환하는 방식을 약속해 놓은 것을 가리켜 함수 호출규약이라 부른다.

 전달 인자를 스택에 쌓는 방법이나 스택 프레임을 반환하는 방식이 하나가 아니기 때문에 미리 약속해 놓는 것이다.

 

CALLBACK함수는 Window 시스템에서 __stdcall을 매크로로 지정한 것이다.

 단순히 이게 아닐수도? Callback 함수란 Window 시스템에 의해 자동으로 호출되는 함수이다. 특정 상황에서 호출되어야 할 함수를 등록시키는 것이 가능한데 이때 등록되는 함수를 가리켜 콜백 함수라고 한다.

 

__cdecl : C/C++ 디폴트 호출 규약

 

 

11 쓰레드의 이해

1. 쓰레드란 무엇인가?

 

다시 컨텍스트 스위칭

 프로세스의 상태 정보를 저장하고 복원하는 일련의 과정이다. 성능 저하의 원인이고.

 컨텍스트 스위칭은 멀티 프로세스를 운영하기 위해 필요하다. 근본적으로 본다면 프로세스는 서로 완전히 독립적이기 때문이라고도 볼 수 있다. A 프로세스에는 A프로세스 데이터만 저장되므로 B프로세스를 위해서는 A프로세스가 사용하는 CPU 자리를 완전히 넘겨줘야한다. CPU 뿐만 아니라 메모리 까지 자리를 내줘야한다.(?)

프로그램이 서로 다르다면 프로세스는 서로를 공유할 수 없다. 하지만 하나의 프로그램에서 둘 이상의 실행 흐름을 두기 위해서는 프로세스처럼 모든 것을 독립적으로 둘 필요는 없다. 이렇게 등장한 것이 쓰레드이며 스레드와 프로세스의 가장 큰 차이점이다.  

자세하게 생각해보면 레지스터 자체에서는 프로세스를 교체하나 쓰레드를 교체하나 컨텍스트 스위칭에 별 차이는 없다. 그러나 캐시 메모리를 고려해서 생각하면  쓰레드가 훨씬 빠르다는 것을 알 수 있다. 쓰레드가 변경되더라도 캐시에 존재하는 메모리를 교체 없이 사용할 수 있기 때문이다 (스택을 제외한 데이터 영역은 공유되므로). 반면 프로세스가 교체되면 캐시에 저장된 메모리는 사용할 수 없으므로 모두 RAM에서 새로 가져와 교체해줘야한다.

저장하고 복원하는 컨텍스트 정보의 개수를 줄여주는 방법으로 컨텍스트 스위칭에 소요되는 시간을 줄일 수 있다. 컨텍스트 정보는 프로세스의 상태 정보와 관련이 있으므로 프로세스 상태 정보를 줄인다는 말과 동일하다.

 

프로세스는 완전히 독립된 두 개의 프로그램 실행을 위해서 사용된다.

쓰레드는 하나의 프로그램 내에서 둘 이상의 프로그램 흐름을 만들어 내기 위해 디자인 된 것이다.

 

쓰레드는 쓰레드간 공유하는 상태정보가 있다. -> 컨텍스트 스위칭을 빠르게 하는 요ㅗ이닝다.

프로세스처럼 완벽히 독립적인 구조가 아닌 쓰레드끼리 공유하는 요소가 있다. 이 요소 덕분에 컨텍스트 스위칭이 프로세스에 비해  빠르다.

 

프로세ㄴ스는 메모리 구조상 다른 프로세스와 완전히 독립적이다. 각각이 stack heap data code 영역을 가지고 있으며 서로 데이터를 주곧 받기 위해서 IPC가 필요하다.

 

스레드는 생성하면 해당 스레드만을 위한 stack 영역만 생성하고 그 이외의 영역은 프로세스 영역을 공유한다.

 

스레드의 특징 : 스레드마다 스택을 독립적으로 할당한다.

 스택은 함수 호출 시 필요한 메모리 영역이다. 실행 흐름의 추가를 위한 최소 조건이 독립된 스택이라고 볼 수 있다. 그리고 실행 흐름은 함수 단위로 이루어진다고도 정리하면 되겠고.

 

스레드의 특성 : 코드 영 역을 공유한다.

코드 영역 : 작성한 코드가 이진화된 명령어로 변환되어 있는 데이터이다.

코드 영역이 공유된다는 것은 프로세스에 있는 명령어(함수 등)를 쓰레드에서도 사용할 수 있다는 것이 된다. 프로세스에 있는 함수를 스레드는 호출할 수 있다.

 

 

스레드의 특성 : 데이터 영역과 힙영역을 공유한다.

따라서 IPC 통신기법 없이 전역변수나 동적 메모리 공간을 공유할 수 있다.

 

Window 시스템에서는 프로세스는 단순히 쓰레드를 담는 상자이다.

 스레드가 없는 프로세스는 존재하지 않으며프로세스 내에서 기본적으로 생성되는 스레드에 의해 main 함수가 호출된다. 이러한 스레드를 main 스레드라고 한다 ( main 함수를 호출하는 스레드)

 

 

2. 쓰레드 구현 모델에 따른 구분

커널레벨 쓰레드 vs 유저레벨 쓰레드

 쓰레드 기능을 제공하는 주체가 누군지에 따라 나눠진다.

 

커널레벨 쓰레드

 쓰레드를 생성 및 스케줄링 하는 주체가 커널인 경우, 커널레벨 쓰레드라고한다.

 커널레벨에서 쓰레드가 지원된다는 뜻이다.

 스케줄러와 스레드 정보는 커널영역에 존재한다. 따라서 운영체제는 쓰레드의를 확인할 수 있다.

 스케줄러는 쓰레드를 대상으로 스케줄링한다.

 

유저레벨 쓰레드

 커널에 의존적이지 않은 형태로 쓰레드의 기능을 제공하는 라이브러리를 활용할 수 있는데 이러한 방식으로 제공되는 쓰레드가 유저레벨 쓰레드이다.

 유저영역에서 실행된다.

스케줄러가 스케줄링하는 대상은 프로세스이다(쓰레드가 아니다)

커널 영역에는 쓰레드에 대한 정보가 존재하지 않으므로 운영체제는  쓰레드의 존재를 알 수 없고 확인도 불가능하다.

 

 

 커널영역 : 운영체제라는 하나의 소프트웨어를 실행시키기 위해서 필요한 메모리 공간이다.

 유저영역 커널영역 외 메모리 공간, 즉 운영체제가 아닌 프로그램을 실행시키기 위 해서 필요한 메모리 공간이다.

 

커널영역과 유저영역을 분리한 이유 : 안전성을 위해서이다. 운영체제에서 오류가 생긴다면 컴퓨터 전체에 문제가 생긴다. 따라서 유저가 직접 커널에 접근할 수 없도록 영역을 아예 분리시킨 것이다.

 

스케줄러가 동작하려면 커널 모드로 전환되어야 한다.

 유저모드에서는 커널영역에 접근이 불가능하다.

 커널모드에서는 eahems 영역의 접근이 허용된다.

 

 모드 전환은 시스템에 붖담을 준다.

 유저모드와 커널모드를 제공하는 것은 프로세서이다. (메모리 보호기능은 CPU에게 있다)

 

 

커널레벌 쓰레드

장점

 커널에서 직접 제공해주기 때문에 안전성과 다양한 기능성이 제공된다.

단점

 커널에서 제공해주는 기능이므로 유저모드에서 커널모드로의 전환이 빈번하게 일어난다. 따라서 이는 성능의 저하로 이어지게 된다.

 

유저 레벨 쓰레의 장점 및 단점

장점 ;  커널은 쓰레드의 존재조차 모른다. 오로지 유저 모드로 동작하기 때문에 유저 모드에서 ㅋ ㅓ널 모드로의 전환이 필요 없다. 때문에 성능이 좋다.

 

단점 ; 운영체제는 프로세스의 존재만 알고 쓰레도의 존재를 모른다. 따라서 결과를 예측하기 어렵게 된다. (쓰레드 이후 여러 쓰레드가 동작하는 구조에서 첫번째 쓰레드가 정지되면 운영체제는 나머지 쓰레드의 존재를 모르므로 나머지 쓰레드도 동작할 수 없게된다. )

 

 

 

13 쓰레드 동기화 기법1

1. 쓰레드 동기화란 무엇인가?

스레드 동기화 : 쓰레드의 실행순서를 정의하고 이 순서대로 실행되도록 하는 것이다. 또한 메모리 접근에 있어서 동시접근을 막는 것 또한 쓰레드의 동기화에 해당한다.

 

유저모드 동기화 : 동기화를 유저 영역에서 진행하는 기법이다. 커널 모드로 전환하지 않으므로 성능상 이점이 있으나, 기능의 제한도 존재한다.

 

컬너모드 동기화 : 동기화를 커널 영역에서 진행하는 기법이다.  커널 모드로 전환해야하므로 성능은 떨어지지만 커널 영역에서 제공하는 기능을 제공받을 수 잇다.

 

2. 임계 영역 (Critical Section)접근 동기화

원래 임계 영역이란 이상의 쓰레드가 동시에 실행될 경우 생길 있는 동시 접근 문제를 발생시킬 있는 코드 블록 임계 영역이라고 한다.

 

임계영역이란 배타적 접근( 순간에 하나의 쓰레드만 접근) 요구되는 공ㅇ유리소스에 접근하는 코드 블록이다.

 

임계 영역에 대한 해결책은 임계 영역의 동시접근을 막는 것이다.

 

 *앞으로 살펴볼 크리티컬, 인터락, 뮤텍스, 세마포어 동기화 기법들은 단순히 임계 여영ㄱ 접근을 제한하기 위한 동기화 방법이다(메모리 접근에 대한 동기화라고도 있다.) 쓸데ㅡ의 실행 순서를 동기화하는 기법은 14장에서 알아볼 것이다.

 

 

3 유저모드 동기화

 

크리티컬 섹션 기반의 동기화 (코드블록 자체를 의미하는 임계영역과 동음이의어)

크리티컬 섹션 오브젝트를 만들고 초기화 한다.

임계영역이 시작되기 전에 크리티컬 오브젝트 섹션을 획득하고 임계영역이 끝나면 크리티컬 섹션 오브젝트를 반환하는 원리이다. 이러한 크리티컬 섹션 오브젝트를 통해 순간에 하나의 쓰레드만 실행될 있게 되는 것이다.

 

 

인터락 함수 (Interlocked Family of Function) 기반의 동기화

 함수 내부적으로 순간에 하나의 쓰레드에 의해서만 실행되도록 동히화되어있다.

 

Volatile 키워드 : 최적화를 수행하지 않고, 메모리에 직접 연산하는 키워드이다.

외부요인으로 인해 변수의 값이 언제든지 변할 있는 경우 volatile 키워드를 사용한다.

컴파일러는 변수에 대해서 최적화를 수행하지 않는다. 또한 변수를 참조하는 경우 레지스터에 로드된 값을 사용하지 않고 매번 메모리를 참조한다.

? 멀티 쓰레드 환경에서는 서로 공유되는 전역변수에 대한 값은 언제든지 변할 있기 때문이다.

 

 

 

 

 

 

 

4 커널모드 동기화

뮤텍스 기반 동기화

 뮤텍스는 뮤텍스 오브젝트를 생성하는 쓰레드에게 기회를 먼저 줄 수 있다.

 생성되는 뮤텍스는 커널 오븢게터 : 커널 레벨 동기화 기법

 초기화 함수의 호출이 필요 없다 ( 크리티컬 섹션 동기화 기법과의 차이점)

  생성함수 과정에 서 필요한 초기화가 모두 이루어지기 때문이다.

 

임계영역에 진입하기 앞서 ㅁㅠ텍스를 획득한다. 뮤텍스가 획득 가능한 상태라면 커널 오브젝트는 signaled 상태이다. 뮤텍스를 획득하게되면 해당 커널 오브젝트 상태는 Non_Sinaled 상태로 변경되어 다른 쓰레드들은 임계영역에 진입할 수 없게된다.

 

 커널 오브젝트의 상태를 이용하여 임계영역 진입점을 구분짓는다. (커널 오브젝트 상태는 쓰레드가 실행중인지 종료중인지를 확인할 수 있다)

 

 

세마포어(Semaphore) 기반의 동기화

커널모드동기화이며 뮤텍스와 비슷하다고 할 수 있다.

차이점은 카운트라는 개념이 존재한다는 점이다. 해당 임계 영역에 접근 가능한 숫자를 미리 설정해둔 후 세마포어 동기화가 실행될때마다 카운트를 줄인다. 카운트가 0이되면 해당 임계영역에 더 이상의 쓰레드는 접근할 수 없게된다. , 설정해놓은 수만큼의 쓰레드가 접근할 수 있는 동기화 기법이다.

 

이름있는 뮤텍스를 사용하는 이유는윈도우가 관리하고 있는 커널 오브젝트에 접근 가능한 핸들 정보를 얻기 위해서이다.

 .. 뮤텍스는 커널 오브젝트이므로 특정 프로세스 영역에 존재하는 것이 아니야. 커널이 관리하는 오브젝트이므로 해당 뮤텍스를 생성하지 않은 다른 프로세스에서도 접근이 가능하다.

 다만 핸들의 유효성이 문제이다. :>>>> 핸들과 핸들 테이블의 소유 및 유효성에 대한 내용확인

 

핸들 테이블은 커널 오브젝트와 이를 지칭하는 핸들값에대한정보를 담고있는 테이블이다. 프로세스별로 독립적이다. 따라서 특정 프로세스는 다른 프로세스에서 생성된 뮤텍스에 접근이 불가능하다. 다른 프로세스를 통해 만들어진 커널 오브젝트인 관계로 핸들 테이블에 대한 정보가 없기 때문이다. >>> 이거 잘 이해가 안된다. 프로세스간 통신으로 해결할 수 없는 문제인가? 그리고 애초에 핸들 테이블에 대한 개념을 까먹음

 

이러한 문제 때문에 뮤텍스에 이름을 붙여주는 것이다. 이 이름은 Windows 운영체제 내에서 유일한 이름이다. 이 이름을 통해 Windows 가 관리하고 있느 커널 오브젝트에 접근 가능한 핸들 정보를 얻을 수 있다.

 

뮤텍스의 소유와 WAIT_ABANDONED 

세마포어는 세마포어를 획득한 쓸데ㅡ와 반환하는 쓸레드가 달라도 문제없다.

그러나 뮤텍스는 그렇지 않다 ( 이거도 잘 이해가세마포어도 같아야하지 않나?)

 

 

14 쓰레드 동기화 기법2

1. 실행순서에 있어서의 동기화

스레드 동기화 : 쓰레드의 실행순서를 정의하고 이 순서대로 실행되도록 하는 것이다. 또한 메모리 접근에 있어서 동시접근을 막는 것 또한 쓰레드의 동기화에 해당한다. 추가로 이야기하자면 메모리 접근에 대한 동기화(임계 영역 접근에 대한 동기화) 역시 쓰레드의 실행 순서 동기화에 포함되는 개념이다. 다만 포커스가 어떠한 것인지를 부각하기 위해서 나눴을 뿐이다.

 

생산자 소비자 모델

 하나의 쓰레드가 입력과 출력을 모두 관리한다면출력속도보다 빠르게 입력되면 제대로 출력되지않는 문제가 발생하게 된다.

이러한 문제를 해결하기 위해 입력 출력 쓰레드를 따로 분리하고, 그 사이에 메모리 버퍼를 둔다.

이처럼 쓰레드의 실행 순서를 동기화하는 일을 생산자 소비자 모델이라고 할 수 있다.

 

 

 

이벤트 기반 동기화

 세마포어, 뮤텍스와 같이 이 기법역시 동기화를 위한 오브젝트를 사용한다. 명칭은 이베늩 오브젝트이다. 보편적으로 이벤트라고만 부르기도 한다.

이벤트 오브젝트 활용방법

 쓰레드나 프로세스의 커널 오브젝트는 초기에 non_signaed,  종료되는 경우 자동으로 signaled 상태로 변경된다.

그러나 이벤트 오브젝트는 종료할 때 직접 sinaled 상태로 변경해줘야한다.

직접 함수 호출을 통해 이벤트 오브젝트의 상태를 sinaled 상태로 변경해야한다.

 

 

이벤트 커널 오브젝트는 ㄹ프로그래머의 요청에 의해 Signaled 상태가 된다.

자동리셋 모드 오브젝트라면 non_signaled 상태로의 변화가 자동으로 이루어짐

수동리셋모드 이벤트는원하는 타이밍에 둘 이상의 스레드를 동시에 깨워서 실행해야할 때 아주 좋음. 하지만 둘 이상의 스레드 순서는 텍스를 함께 사용해야 해결가능하다.

잘이해못했어 인터네 ㅅ 찾아보자.

 

 

2. 이벤트 더하기 뮤텍스

 

 

블로그 이미지

연한그린커리

,

C#2

언어/C# 2020. 1. 24. 16:14

문자열 다루기

 

{0}, {1} 서식 항목 format item

 

추가 옵션

 서식 항목 첨자

 왼/오 맞춤

 변환 서식 지정 문자열

 

 

Console.WriteLine("Total : {0, -7 : D}", 123); // 첨자0, 맞춤:-, 서식 문자열: D

 

 

왼쪽 오른쪽 맞춤

 서식 항목의 맞춤 옵션을 지정하면 해당 서식 항목이 차지할 공간의 크기를 선택할 수 있고, 

 그 공간안에서 왼쪽or오른쪽에 데이터를 할당할지 결정 가능하다.

 

 

 

 

'언어 > C#' 카테고리의 다른 글

C#  (0) 2020.01.18
블로그 이미지

연한그린커리

,

C#

언어/C# 2020. 1. 18. 19:25

1. 처음 만드는 C# 프로그램

 

세미콜론 사용 이유

긴 문장을 여러 줄에 걸쳐 사용하거나 짧은 여러 문장을 한줄에 몰아 넣을 때 세미콜론을 사용하여 문장을 마치는 방법이 그렇지 않은 방법보다 훨씬 유용한다는 것을 알 수 있다.


클래스 
C# 프로그램을 구성하는 기본 단위로서 데이터와 데이터를 처리하는 기능(메소드)로 이루어진다.


CLR( ( Common Language Runtime)
C#으로 만든 프로그램은 CLR 위에서 실행된다.
.NET 프레임워크와 OS 위에 설치된다. 
C# 컴파일러가 만들어낸 실행 파일은 하드웨어가 이햏랄 수 없는 코드로 구성되어 있기 때문에 실행할 수 없다. 

C#컴파일러는 C# 소스코드를 IL(Intermediate Language)라는 중간 언어로 작성된 실행 파일을 만들어 낸다.
사용자가 이 파일을 실행시키면 CLR이 중간 코드를 읽어 들여 다시 하드웨어가 이해할 수 있는 네이티브 코드로 컴팡리한 후 실행시킨다. 이것을 JIT(Just In Time 컴파일) 이라고 한다. = 적시 컴피ㅏ일 

JIT 컴파일이란 실행에 필요한 코드를 실행할 때마다 실시간으로 컴파일해서 실행한다는 뜻이다.


C#컴파일러가 C# 소스코드를 IL 중간언어로 컴파일하여 실행파일을 만듬
CLR이 IL 중간 코드를 읽어 하드웨어가 이해할 수 있는 네이티브 코드로 컴파일하여 실행하는 JIT 컴파일 수행


즉 두번의 컴파일이 수행된다는 것이다. 왜 이렇게 하는가?
 CLR은 C#뿐만 아니라 다른 언어도 지원되도록 설계되어 있다. C#만을 컴파일할 목적이라면 C# 소스 코드를 바로 네이티브 코드로 변환시키면 되지만, 다른 언어도 컴파일해야하므로 컴파일 가능한 모든 코드를 IR 중간언어로 컴파일하고, 하나의 언어로 번역된 IR 코드를 네이티브 코드로 번역하는 것이다.

장점은 플랫폼에 최적화된 코드를 만들어낼 수 있다.는 것.
 (CLR이 자신이 설치 되어 있는 플랫폼에 IR 코드를 최적화 시켜 컴파일 하기 때문이다.)
단점은 컴핑리 비용이 증가하ㄴ다는 것이다. (그러나 컴파일 비용은 사용자에게는 부담이 없음)

 

 

 

 

 

2. 데이터 보관하기

 

 

 

 

3. 기본 데이터 형식의 사용 방법 익히기

4. 상수가 무엇인지 알아보고 사용 방법을 익히기

5. Nullable 형식을 이해하기

6. C#의 데이터 형식과 공용 형식 시스템의 관계를 이해하기

 

 

데이터 형식이란?

 소프트웨어에 필요한 데이터를 편리하게 사용할 수 있도록 데이터의 형식을 미리 만들어 제공한다.

 데이터 형식은 수와 텍스트는 물론, 이미지나 소리를 다룰 수 있는 형식도 존재한다.

 C#은 기본 본 데이터 형식과 복합 데이터 형식을 지원한다. (값 형식과 참조 형식으로도 분류할 수 있ㄷ)

 

값 형식 : 데이터에 값이 직접 포함되는 형식이다. 

 값 형식 변수 하나를 다른 변수에 대입하면 변수에 폼함된 값이 '복사'된다.

 모든 값 형식은 암시적으로 System.ValueType에서 ㅍ ㅏ생ㄷ왼다.

 값 형식에서는 새 형식을 파생시킬 수 없다 (참조 형식ㄷ과과 대비)

 구조체는 참조 형식과 마찬가지로 인터페이스를 구현할 수 있다.

 값 형식에는 null값이 포함될 수 없다 ( 참조와 대비)

 

 

 

참조 형식 : 데이터에 대한 참조가 저장되는 방식이다.

두 가지 변수가 같은 개체를 참조할 수 있으므로 한 ㅂ녀수에 대한 작업이 다른 변수에서 참조하는 개체에 영향을 미칠 수 있다. (값 형식과 대비)

 

참좋 형식에는 클래스, 인터페이스, 델리게이트가 있다.

다이나믹, 오브젝트, 스트링의 기본 참조 형식도 존재한다.

 

 

 

 

 

참조 형식 변수의 경우 위의 상황에서 개체 자체가 아니라 개체에 대한 참조가 복사된다.

 

https://parksh86.tistory.com/114

 

기본 데이터 형식

 

15가지

숫자 형식, 논리 형식, 문자열 형식, 오브젝트 형식으로 나눠진다.

 

문자열, 오브젝트 형식은 참조 형식

나머지는 값 형식

 

 

숫자 형식

 

 정수 계열 형식 : 정수 데이터를 담기 위해 사용하는 형식

 D

 

 

 

오버플로우 : 데이터 형식의 최대값을 넘어가는 데이터를 저장할 때 일어나는 현상

 새로운 자리수의 비트(저장 불가능한)는 버려짐.

 

언더플로우 : 데이터 형식의 최소값보다 작은 데이터가 저장될 때 일어나는 현상.

 

CHAR : 정수계열이라고 한다.

 

부동 소수점 형식

 소수점이 고정되어 있지 않고 움직이면서 수를 표현한다는 뜻에서 붙여진 이름.

 고정 소수점을 이용할 때보다 더 제한된 비트로 훨씬 넓은 범위의 값을 표현할 수 있기 때문에 사용한다. 

 

부동 소수점은 정수를 대체하지 못한다. 

 소수점 표현을 위해 일부 비트를 사용하기 때문에 정수 계열의 크기를 표현하는데 제한이 있다. 

 부동 소수점 형식은 산술 연산 과정이 정수 계열 형식보다 복잡해서 느리다.

 

float, double 이 부동 소수점 형식에 속한다.

 

 

문자, 문자열 형식

char, string 

char는 정수, 문자 둘다 

 

논리형식 

  bool : 1비트면 표현할 수 있으나 컴퓨터가 기본으로 다루는 데이터의 크기가 바이트 단위이므로 1byte를 통채로 사용

 

 

Object 형식

 

 어떤 데이터든지 다룰 수 있는 데이터 형식 -> 상속 덕분에 가능.

 object가 몯느 데이터를 다룰 수 있도록 "모든 데이터 형식(기본, 복합, 사용자 정의 모두 포함)이 자동으로 object 형식을 상속받게 한 것이다. = 모든 데이터 형식의 조상이 object 형식이다 (여기서 말하는 상속은 클래스의 상속과 기능은 유사하다. 다만 상속의 대상이 클래스가 아닌 데이터 형식인 상황이다)

 

 이러한 기능으로 인하여 어떠한 데이터라 할지라도 ojbect에 담아 처리할 수 있게 되는 것이다.

 

그러나

 float 형식의 부동 소수점 방식, decimal 형식은 소수를 처리하는 방식이 다르고

 s(igned) 유무에 따라 부호 있는 형식과 부호 없는 형식을 처리하는 방식이 다르다.

 그렇다면 object는 위와같은 상황이 발생했을 때 어떤 기준에 의해 처리하는 방식을 선택하는 것인가?

  0>>>  이거 해결방법은 아직 안나옴...

이 문제를 이해하기 위해서 박싱, 언박싱 메커니즘을 이해해야 한다.

 

object는 참조 형식이므로 힙 공간에 데이터를 할당한다. 

ojbect에 들어가는 값은 float이나 double같은 값 형식 데이터가 저장될 수 있다. 

 

object 형식은 값 형식의 데이터를 힙에 할당하기 위하여 boxing 기능을 제공한다.

ojbect 형식에 값 형식 데이터를 할당하려는 시도가 일어난다면 ojbect 형식은 Boxing을 수행ㅇ하여 해당 데이터를 힙에 할당한다.

object a = 20;

 

반대로 Boxing된 값을 꺼내 값 형식 변수에 저장하는 과정을 Unboxing이라고 한다.

object a = 20;

int b= (int)a;

 

 

데이터 형식 변경하기

 

 

 1.크기(표현 범위)가 서로 다른 정수 형식 사이의 변환

 작은 정수 형식의 변수를 큰 정수 형식의 변수로 옮긴다면 문제 없음.

 큰 정수 형식을 작은 변수 형식으로 옮긴다면 '오버 플로우'가 발생한다.

 

2. 크기(표현 범위)가 서로 다른 부동 소수점 형식 사이의 변환

 

부동 소수점 형식의 특성상 오버 플로우는 발생하지 않으나 '정밀성'에 손상을 입게된다.

 

 

3.부호가 있는 정수 형식과 부호 없는 정수 형식 사이의 변환

 int 형식에 음수를 담고 음수를 표현할 수 없는 uint 형식에 형변환 한다면 언더 플로우가 발생한다.

 

4. 부동 소수점 형식과 정수 형식 사이의 변환

 부동 소수점 변수 -> 정수 == 소수점 아래는 버려지고 소수점 위 값만 남는다 (0.1 = 0)

 

5. 문자열 <> 숫자 변환

 C#은 정수 계열, 부동 소수점 형식 모두에 Parse()라는 메소드를 이용하여 문자열->숫자 변환이 가능하게 한다.

 또한 object로부터 물려받은(오버라이딩된) ToString()메소드로 숫자->문자열 변환이 가능하다.

 

 

상수와 열거 형식

 상수와 열거형식은 안에 담긴 데이터를 절대 변경할 수 없는 메모리 공간이다.

 상수는 c++과 동일하게 const 키워드를 붙여 사용한다. 

 프로그래머의 실수를 방지하기 위해 사용한다. (값이 변경되어서는 않되는 변수를 상수화 하는 방법으로)

 

 열거형식

  열거형식 마찬가지로 c++과 동일하게 enum 키워드를 이용한다.

  상수가 너무 많아진다면 프로그래머가 혼동할 수 있으므로 enum으로 문자화하여 사용한다.

 

 

Nullable 형식

 C#은 변수를 초기화 하지 않고 사용하려 한다면 컴파일 오류를 일으킨다.

 그러나 특정 상황에서는 초기화 하지 않은 변수가 필요할 수도 있다. 

 이러한 경우 Nullable 형식을 이용하는 것이다.

 사용방법 : 원래의 데이터 형식 이름 뒤에 '?'을 붙인다.

 int? a = null; ( int? a; 이렇게만 하면 Nullable이 적용되지 않아 사용하려고 할 때 컴파일 오류가 발생한다.)

  - 값 형식은 비워둘 수 없는 데이터이므로 null로만 초기화 한다면 오류가 생긴다.

 Nullable 형식을 사용할 수 있는 경우는 '값 형식'인 경우에만 가능하다. = 참조 형식에서는 불가능하다. 

  - Object a = null; 이러한 형태는 가능. 

 

모든 Nullable 형식은 HasValue와 Value 두 가지 속성을 지닌다. ( 속성은 c++ 멤버변수처럼 사용한다 a.HasValue)

 

HasValue : 해당 Nullalbe 변수가 값을 갖고 있는지 않은지를 나타낸다.

Value : 해당 Nullable 변수에 담겨있는 값을 나타낸다.

 

 

 

C# 컴파일러의 특성과 var 키워드

 C#은 변수 상수 등에 대한 컴파일을 세밀하게 수행하는강력한 형식의 언어 Strong Typed Language 이다. 

 이러한 특징은 프로그래머의 실수를 줄일 수 있다는 장점이 있다. ( 의도치 않은 데이터 형식을 읽거나 할당하는 일방지

 

 이러한 형식과 상반되는 약한 형식의 검사는 코드를 작성하는 단계에서 좀 더 편리하다는 장점이 있다.

  데이터 형식을 지정하지 않고 변수를 선언해서 데이터를 할당하면 컴파일러가 알아서 값을 보고 변수의 형식을 지정하기 때문이다.

 

C#은 var 키워드를 통해 해당 키워드를 선언한 부분에 대하여 약한 형식의 검사를 하게하는 기능을 가지고 있다. 

 데이터 형식을 지정하지 않고 var으로 선언하면 위와같은 편의성을 사용할 수 있게된다. 

 var a = 3;  // int a = 3;

 

var 키워드는 '지역 변수로만 사용'가능하다. 

클래스의 필드를 선언할 때는 반드시 명시적 형식을 선언해야한다. 

  클래의 필드는 선언과 같이 초기화를 하지 않는 경우가 많은데... var zl키워드로 필드를 선언하면 컴파일러가 형식을 알 수 없 게 되기 때문이다. 

 

참고로 C#에서는 전역 변수를 더이상 지원하지 않는다고 한다.

 

 

object a = 20; 

var b = 20; 

 

둘의 차이점은

 전자는 CLR이 박싱해서 20을 힙에 넣고 a가 힙ㅇ을 가리키도록 만드로고

 후자는 컴파일 시점에서 컴파일러가 a에 적합한데이터 형식을 파악해서 int a = 20; 으로 바꿔 컴파일하는 것이다.

  CLR이 해당 코드를 실행하게된 시점에서는 a 가 var로 선언되었는지 모르고 int 형식으로 객체 a에 20을 담아 스택에 올리는 것이다.

 

 

 

공용 형식 시스템

 C#의 모든 데이터 혀ㅑㅇ식 체계는 공용 형식 시스템 CTS(common type system) 이라는 .NET 프레임워크의 형식 체계의 표준을 그대로 따르는 것이다. 

 

이로인하여 .NET 언어들 끼리 서로 호환성을 가지게 되는 장점이 있다. 

 

 

확인

 값 형식과 참조 형식의 차이

 박싱과 언박싱

 

'언어 > C#' 카테고리의 다른 글

C#2  (0) 2020.01.24
블로그 이미지

연한그린커리

,

알고리즘

알고리즘 2020. 1. 14. 22:41

정렬 아록리즘

 

알고리즘이란

 문제를 해결하기 위한 ㅇ리련의 명령이나 반복되는 절차.

 

 

정렬 알고리즘

 

정렬을 하는 이유 : 탐색을 쉽게 하기 위해서.

 

 

1. 버블 정렬 ( Bubble sort)

 

정렬의 대상을 줄여나간다. 

데이터가 어떠한 방식으로 정렬되었는지와 상관 없이 항상 같은 횟수의 비교 연산을 거친다.

n(n-1) / 2 의 비교 연산으로 정렬 알고리즘을 수행. (가우스 초식을 연상 n-1 + ... + 1)

 

 

 

 

 

삽입 정렬 (Insertion Sort)

 

정렬으리 대상을 늘려나간다.

데이터가 이미 정렬된 상태라면 비교 연산을 거치지 않는다. ( 데이터의 정렬 상태에 따라 연산 횟수는 유동적)

 

버블 정렬과 반대로 정렬 대상을 늘리면서 연산하므로 가우스 초식의 역을 연상한다. ( 1 + 2 + .. + n-1)

다만 데이터 정렬 상태에 따라 최선의 경우와 최악의 경우로 나뉘므로 이것의 평균을 구한다면 n^2 + n -1 / 2 이다.

즉, 버블 정렬에 비해 삽입 정렬이 평균적으로 더 나은 성능을 보인다. (그러므로 크기가 작은 데이터 집합을 정렬한다면 버블 정렬보다는 삽입 정렬을 사용하는 편이 효율적이다.)

 

 

 

퀵 정렬 (Quick Sort)

 

분할 정복 (Divide and Conquer)에 기반한 알고리즘

 

분할 정복 알고리즘이란... 전쟁 전략에서 중 하나인 분할 정복에 기반한 알고리즘이다. 적군의 전체를 공략하는 대신, 전체를 구성하는 구성 요소들을 나누어 잘게 쪼개진 적을 공략하는 전법인 분할 정복처럼 전체를 구성하는 구성 요소들을 나누어 연산을 수행하는 알고리즘인 것이다.

 

1. 데이터 집합 내에서 임으의 기준 요소를 선택하고, 기준 요소보다 작은 요소들은 순서에 관계없이 무조건 기준 요소의 왼편에, 큰 값은 오른편에 위치시킵니다.

 

2. 기준 요소 왼편에는 기준 요소보다 작은 요소들이 모여 있고 오른편에는 큰 요소들이 모여있다. 나누어진 데이터 집합ㅇ들을 다시 1에서와 같이 임의의 기준 요소를 선택하고 같은 방법으로 데이터 집합을 분할한다.

 

3. 이러한 과정을 더이상 데이터 집합을 나눌 수 없을 때까지 반복하면 정렬된 데이터 집합이 만들어진다.

 

 

 

 

 

블로그 이미지

연한그린커리

,

우선순위 큐(Priority Queue) 와 힙(Heap)

 

우선순위 큐는들어간 순서에 상관 없이 우선순위가 높은 데이터가 먼저 나온다.

(응급실 - 생명이 위급한(우선순위 높은) 환자가 먼저 응급실에 들어간다)

 

구현방법

 

1. 배열 기반으로 구현

 데이터의 우선순위가 높을 수록 배열으리 앞쪽에 데이터를 위치시킨다.

 단점 

  데이터를 삽입 삭제하는 과정에서 데이터를 한칸씩 뒤로 밀거나 당겨야하는 비효율적인 연산을 수반한다.

  삽입 위치를 찾기 위해 배열에 저장된 모든 데이터와 우선순위 비교 연산을 진행해야 한다.

 

2. 연결 리스트를 기반으록 구현

 데이터의 우선순위가 높 을 수록 리스트의 앞쪽에 데이터를 위치시킨다.

 배열처럼 데이터 삽입, 삭제 시 이후 모든 데이터를 한칸씩 밀거나 당겨야하는 비효율적인 연산을 수반하지 않는다.

 단점 

  첫번째 노드부터 마지막 노드까지 우선순위 비교 연산을 진해해야 한다 (배열 기반과 동일한 단점)

 

이러한 단점 때문에 우선순위 큐는 힙을 이용하여 구현하는 것 일반적인 방법이다.

 

3. 힙을 이용하여 구현

 

힙이란?

 이진 트리 중 완전 이진트리에 속하는 구조이다.

 모든 노드에 저장된 값은 자식 노드에 저장된 값보다 크거나 같아야 한다.  = 루트 노드에 저장된 값이 가장 커야 한다.

 (우선순위가 높다는 것을 의미 : 값이 작은 것이 우선순위가 높은 구조일 수도 있다)

 

최대 힙(max heap) : 루트노드로 올라갈수록 저장된 값이 커지는 완전 이진트리

최소 힙(min heap) : 루트노드로 올라갈수록 저장된 값이 작아지는 완전 이진트리

 

 

우선순위 큐는 힙이 어울리므로 이제 힙을 구현하는 방법을 고민해야한다.

 

힙을 구현하는 방법 ( 힙 = 완전 이진 트리 = 배열  or 연결 리스트를 이용하여 트리 구현)

1. 배열

 이진트리 구조를 가지며 이러한 구조를 유지해야 하는 힙은 배열 기반으로 구현하는 것이 적합하다. 

 

2. 연결리스트

 연결 리스트 기반으로 힙을 구현하면 마지막 위치에 추가하는 일이 배열기반 구현보다 더 많은 연산을 필요로 한다.

 

 

 

 

 

 

'자료구조' 카테고리의 다른 글

  (0) 2020.01.07
스택  (0) 2020.01.02
트리  (0) 2019.12.29
자료구조 1.연결 리스트(Linked List) - 배열 기반  (0) 2019.12.28
블로그 이미지

연한그린커리

,