동시성 처리

동시성 처리


공짜 점심은 끝났다.

  • 소프트웨어는 동일한데 CPU가 빨라지면 덩달아 빨라지는것
  • Scale Up

성능 향상 특이점 이후의 CPU

  • CPU는 더 이상 빨라지지 않고 더 많은 일(다중 코어)을 동시에 할 수 있게 발전 (-> Scale Out)

동시성을 고려한 프로그램을 작성해야 한다.

확장성 (Scalability)

  • 하나의 시스템이 성능 향상에 지장을 받지 않고 자원에 대한 수요읠 변화를 수용할 수 있는 정도
  • 수요의 증가를 수용할 때 자원을 추가 투입하는 것은 당연하고 단지 그 비율이 선형적이거나 아니면 조금 더 효율적이길 바란다.

동시성 (Concurrency)

  • 확장성을 위한 수단으로써, 하마디로 자원을 더 주면 프로그램이 알아서 잘 활용하는 것
  • 자원을 잘 활용하기 위한 프로그램의 복잡도가 증가하지 않거나 완만하게 증가하기를 바란다.

객체지향 모델링

  • 객체란 은닉한 상태에 대해 지켜야 하는 논리를 보호하는 안전한 동작들만 노출 시킴
  • 시스템은 메서드 호출에 반응하여 내부의 상태를 수정하는, 즉 전체 상태를 진전시키는 동작 호출을 통해 서로와 통신하는 객체 인스턴스의 네트워크로 표현

멀티쓰레드

  • 객체에서의 은닉이라는 것은 멀티쓰레드 환경을 고려하지 않았다면 이러한 동작들이 안전하지 않게 되며 내부 상태 오염에 이르게 됨
  • 실제 멀티 쓰레드 환경에서의 시스템은 쓰레드들이 동작 호출을 통해 객체 인스턴스의 네트워크를 따라 이동하는 것

객체지향 모델링의 한계

  • 상태의 은닉만으로는 동시에 동작을 호출하는 것에 대한 보호를 할 수 없음
  • getNext()는 세가지 동작으로 구성
  1. value -> 9
  2. 9 + 1 -> 10
  3. 10 -> value
  4. value -> 10
  5. 10 + 1 -> 11
  6. 11 -> value
1
2
3
4
5
6
7
public class UnsafeSequence {
private int value'

public int getNext() {
return this.value++;
}
}
  • 쓰레드를 제어해야 함

쓰레드

  • 프로세스란 격리되어 있고 독립적으로 동작하는 OS의 관리 단위로 순차적인 실행과 OS의 I/O를 통한 외부와의 통신을 특징으로 함
  • 쓰레드는 프로세스내에서 동시적인 실행과 메모리 공유를 통한 통신
    • 처리량의 향상
    • 메모리 공유라는 것은 비순차성을 의미하며 개발이 복잡해지고 추론이 어려워지는 것을 의미
    • 충분히 동기화하지 않으면 멀티쓰레드에서의 동작들의 순서는 예측 불가
    • 멀티쓰레드라는 것이 전체 성능은 올릴지라도 어느 정도의 런타임 부하를 수반

동시적 프로그래밍

  • 공유하고 변경 가능한 상태에 대한 접근을 통제
  • 멀티 쓰레드에 안전한 코드를 만든다는 것은
    • 상태를 쓰레드간에 공유하지 않는다.
    • 상태를 변경 불가능하게 한다.
    • 상태를 접근할 때 동기화를 사용한다
      • 하나 이상의 쓰레드가 상태에 접근하고 그 중 하나가 변경할 수 있다면 이 모든 쓰레드들은 동기화를 통해 해당 상태에 대한 접근을 순서대로 배열하여야 한다.
1
2
3
4
5
6
7
public class StatelessFactorizer implements Servlet {
public void service(ServiceRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
encodeIntoResponse(resp, factors);
}
}

소인수분해를 하는 서블릿

  • 상태가 없으면 통제할 대상이 없으므로 항상 멀티쓰레드에 안전
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.math.BigInteger;

public clss UnsafeCachingFactorizer implements

servlet {
private BigInteger lastNumber;
private BigInteger[] lastFactos;

public void service (ServletRequest req, ServletResponse resp){
BigInteger i = extractFromRequest(req);
if (i.equals(this.lastNumber) encodingIntoResponse(reqp, this.lastFactors));
else{
BigInteger[] factors = factor(i);
this.lastNumber = i;
this.lastFactors = factors;
encodeIntoResponse(resp, factors);
}
}
}

WIP…

You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.