/ CS

cs - Critical Section, Singleton Pattern, Overloading, Overriding

CS 스터디 공부 목록

1. Critical Section

  • Critical section은 멀티스레드 환경에서 공유 자원에 대한 접근이 제한되어야 하는 코드 영역을 말합니다.(= 한 순간 반드시 프로세스 하나만 집입해야 하는데, 프로그램에서 임계 자원을 이용하는 부분으로 공유 자원의 독점을 보장하는 코드 영역을 의미합니다.)

  • 여러 스레드가 공유 자원에 동시에 접근하면 충돌이 발생하여 예기치 않은 동작이 발생할 수 있습니다. 따라서 이를 방지하기 위해서는 공유 자원을 보호하는 방법이 필요합니다. 이를 위해서 Critical section이라는 개념이 등장하게 되었습니다.

  • Critical section은 한 번에 하나의 스레드만 접근할 수 있는 코드영역입니다. 이를 구현하기 위해 락(lock)이라는 동기화 기술을 사용합니다. 락은 공유 자원에 대한 접근 권한을 가진 스레으가 락을 확보하고, 작업이 끝난 후 락을 해제함으로써 다른 스레드가 접근할 수 있도록 합니다.

  • 락을 사용하여 Critical section을 보호하면, 멀티스레드 환경에서 안전하게 공유 자원에 접근할 수 있습니다. 하지만 락이 잘못 사용될 경우, 데드락(Deadlock)이 발생하거나 성능 저하가 일어날 수 있으므로 주의해야 합니다.

  • 임계 구역은 지정된 시간이 지난 후 종료된다.

    • 공유되는 자원 => 동시에 접근하려고 하는 자원에서 문제가 생기지 않게 보장해주어야 하는 영역이다.(= 임계영역)

임계 영역을 해결하기 위한 방법

  • 크리티컬 섹션 문제에 대한 모든 솔루션은 다음 요구 사항을 충족합니다.
    1. 상호배제: 한 프로세스가 임계 영역에 들어갔을 때, 다른 포르세스는 들어갈 수 없습니다.
    2. 진행률: 임계 구역에서 실행 중인 프로세스가 없고 임계 구역에 진입하려는 프로세스가 있을 때, 진입하기 위해 무한전 기다릴 필요는 없습니다.
    3. 제한된 대기: 다른 프로세스가 임계 영역에 들어가도록 요청한 후 해당 요청이 수락되기 전에 프로세스가 임계 영역에서 실행할 수 있는 횟수에 제한이 있어야 합니다.

2. Singleton pattern

  • 싱글턴 패턴을 따르는 클래스는 생성자가 여러 차례 호출 되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 객체를 리턴한다.
  • 이와 같은 디자인 유형을 “싱글턴 패턴”이라고 한다.

  • 파이썬의 모듈은 그 자체로 싱글턴이다.
# 파이썬
class singleton:
    __instance == None
    def __new__(cls, *args):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls, *args):
        return cls.__instance

3. Overriding And Overloading

  • Overriding과 Overloading은 객체 지향 프로그램(OOP)에서 다형성을 구현하기 위해 사용되는 개념입니다.

    • 여기에서 다형성(Polymorphism)은 객체 지향 프로그래밍에서 여러 개의 클래스가 동일한 메서드나 프로퍼티를 가지고 있을 때, 각 클래스의 인스턴스가 해당 메서드나 프로퍼티를 다르게 처리할 수 있는 것을 말합니다. 즉, 동일한 이름의 메서드나 프로퍼티가 다른 방식으로 동작할 수 있는 것입니다.

    • 다형성은 상속, 추상화, 인터페이스, 오버라이딩 등의 개념들과 밀접한 관련이 있습니다. 예를 들면, 상위 클래스의 메서드를 하위 클래스에서 오버라이딩하여 다른 방식으로 동작할 수 있습니다. 이렇게 하위 클래스에서 상위 클래스의 메서드를 재정의하면, 다형성을 구현할 수 있습니다. 또한, 추상 클래스나 인터페이스를 사용하면, 다른 클래스에서 해당 추상 클래스나 인터페이스를 상속하거나 구현하여 다형성을 구현할 수 있습니다.

3.1. Overloading

  • 두 메서드가 같은 이름을 갖고 있으나 인자의 수나 자료형이 다른 경우입니다.
  • Overloading(오버로딩)은 동일한 이름의 메서드를 매개변수의 개수나 타입 등을 다르게하여 여러 개 정의하는 것을 말합니다. 같은 이름의 메서드나 여러 개 있지만 매개변수의 타입이나 개수가 다르기 때문에 컨파일러는 메서드 호출 시 인자의 타입이나 개수에 맞는 메서드를 자동으로 선택해줍니다. 예를 들면, Print() 메서드는 매개변수의 타입에 따라 여러 버전이 오버로딩됩니다.

  • 아래는 자바에서 사용한 Overloading의 예제 코드입니다.
    # Overloading example
    public double computeArea(Circle c) { ... }
    public double computeArea(Circle c1, Circle c2) { ... }
    public double computeArea(Square c) { ... }
    

3.2. Overriding

  • 상위 클래스의 메서드와 이름과 signature가 같은 함수를 하위 클래스에 재정의 하는 것 입니다.
    • 상속 관계에 있는 클래스 간에 같은 이름의 메서드를 정의하는 것 입니다.
  • Overriding(오버라이딩)은 상위 클래스가 가지고 있는 메서드를 하위 클래스에 재정의하여 사용하는 것을 말하니다. 즉, 하위 클래스에서 상위 클래스의 메서드를 덮어쓰는 것입니다. 이를 통해 다형성을 구현할 수 있습니다. 예를 들면, Animal 클래스에 있는 makeSound() 메서드를 하위 클래스인 Dog 클래스에서 오버 라이딩하여 개 울음소리를 내도록 구현할 수 있습니다.

  • 아래는 자바에서 사용한 Overriding의 예제 코드입니다.
    # overriding example
    public abstract class Shape {
    public void printMe() { System.out.println("Shape"); }
    public abstract double computeArea();
    }
    public class Circle extends Shape {
    private double rad = 5;
    @Override // 개발자의 실수를 방지하기 위해 @Override(annotation) 쓰는 것을 권장
    public void printMe() { System.out.println("Circle"); }
    public double computeArea() { return rad * rad * 3.15; }
    }
    public class Ambiguous extends Shape {
    private double area = 10;
    public double computeArea() { return area; }
    }
    
    • Overrindg과 Overloading은 이름은 유하사지만, 서로 다른 개념이고 용도 또한 다릅니다.
    • Overloading은 같은 이름의 메서드를 다양한 매개변수로 정의하는 것이고,
    • Overriding은 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 재정의하여 사용하는 것입니다.

참고문헌