day71 πŸŒ•

μž₯λ―ΈΒ·2022λ…„ 8μ›” 24일
0

였늘의 μ„±κ³Ό

λͺ©λ‘ 보기
71/129

μŠ€ν”„λ§ DB 1편 - 데이터 μ ‘κ·Ό 핡심 원리 μ„Ήμ…˜ 4 μˆ˜κ°•

+) 22. 09. 03. 정리 μΆ”κ°€!!

μ„Ήμ…˜ 4. μŠ€ν”„λ§κ³Ό 문제 ν•΄κ²° - νŠΈλžœμž­μ…˜ μˆ˜κ°• μ™„λ£Œ!!

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ꡬ쑰

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ꡬ쑰

ν”„λ ˆμ  ν…Œμ΄μ…˜ 계측

  • UI와 κ΄€λ ¨λœ 처리λ₯Ό λ‹΄λ‹Ήν•œλ‹€.
  • μ›Ή μš”μ²­κ³Ό 응닡을 λ‹΄λ‹Ήν•œλ‹€.
  • μ‚¬μš©μž μš”μ²­μ„ κ²€μ¦ν•œλ‹€.
  • μ£Ό μ‚¬μš© 기술: μ„œλΈ”λ¦Ώκ³Ό HTTP 같은 μ›Ή 기술, μŠ€ν”„λ§ MVC

μ„œλΉ„μŠ€ 계측

  • λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ λ‹΄λ‹Ήν•œλ‹€.
  • μ£Ό μ‚¬μš© 기술: 가급적 νŠΉμ • κΈ°μˆ μ— μ˜μ‘΄ν•˜μ§€ μ•Šκ³  순수 μžλ°” μ½”λ“œλ‘œ μž‘μ„±ν•œλ‹€.

데이터 μ ‘κ·Ό 계측

  • μ‹€μ œ λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Όν•˜λŠ” μ½”λ“œλ‹€.
  • μ£Ό μ‚¬μš© 기술: JDBC, JPA, File, Redis, Mongo λ“±

μˆœμˆ˜ν•œ μ„œλΉ„μŠ€ 계측
μ—¬κΈ°μ„œ κ°€μž₯ μ€‘μš”ν•œ 곳은 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직이 λ“€μ–΄μžˆλŠ” μ„œλΉ„μŠ€ 계측이닀. λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ€ μ΅œλŒ€ν•œ 변경없이 μœ μ§€λ˜μ–΄μ•Ό ν•œλ‹€.
μ΄λ ‡κ²Œ ν•˜λ €λ©΄ μ„œλΉ„μŠ€ 계측을 νŠΉμ • κΈ°μˆ μ— 쒅속적이지 μ•Šκ²Œ κ°œλ°œν•΄μ•Ό ν•œλ‹€. μœ„μ™€ 같이 계측을 λ‚˜λˆˆ μ΄μœ λ„ μ„œλΉ„μŠ€ 계측을 μ΅œλŒ€ν•œ μˆœμˆ˜ν•˜κ²Œ μœ μ§€ν•˜κΈ° μœ„ν•œ λͺ©μ μ΄ 크닀.
μ •λ¦¬ν•˜μžλ©΄ μ„œλΉ„μŠ€ 계측은 가급적 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직만 κ΅¬ν˜„ν•˜κ³  νŠΉμ • κΈ°μˆ μ— 직접 μ˜μ‘΄ν•΄μ„œλŠ” μ•ˆ λœλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ ν–₯ν›„ κ΅¬ν˜„ 기술이 변경될 λ•Œ λ³€κ²½ 영ν–₯ λ²”μœ„λ₯Ό μ΅œμ†Œν™”ν•  수 μžˆλ‹€.

MemberServiceV1

@RequiredArgsConstructor
public class MemberServiceV1 {

    private final MemberRepositoryV1 memberRepository;

    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        Member fromMember = memberRepository.findById(fromId);
        Member toMember = memberRepository.findById(toId);

        memberRepository.update(fromId, fromMember.getMoney() - money);
        memberRepository.update(toId, toMember.getMoney() + money);
    }
    
}

MemberServiceV1은 νŠΉμ • κΈ°μˆ μ— 쒅속적이지 μ•Šκ³  μˆœμˆ˜ν•œ λΉ„μ¦ˆλ‹ˆμŠ€ 둜직만 μ‘΄μž¬ν•œλ‹€. νŠΉμ • 기술과 κ΄€λ ¨λœ μ½”λ“œκ°€ 거의 μ—†μ–΄μ„œ μ½”λ“œκ°€ κΉ”λ”ν•˜κ³  μœ μ§€λ³΄μˆ˜ν•˜κΈ° 쉽닀.
ν•˜μ§€λ§Œ 여기에도 남은 λ¬Έμ œκ°€ μžˆλ‹€. λ°”λ‘œ SQLExceptionμ΄λΌλŠ” JDBC κΈ°μˆ μ— μ˜μ‘΄ν•œλ‹€λŠ” 점이닀.
그리고 MemberRepositoryV1μ΄λΌλŠ” ꡬ체 ν΄λž˜μŠ€μ— 직접 μ˜μ‘΄ν•˜κ³  μžˆλ‹€. 이것은 MemberRepository μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ„μž…ν•˜μ—¬ MemberService의 μ½”λ“œ λ³€κ²½ 없이 λ‹€λ₯Έ κ΅¬ν˜„ 기술둜 μ†μ‰½κ²Œ λ³€κ²½ν•  수 μžˆλ‹€.

MemberServiceV2

public class MemberServiceV2 {

    private final DataSource dataSource;
    private final MemberRepositoryV2 memberRepository;

    public void accountTransfer(String fromId, String toId, int money) throws SQLException {

        Connection con = dataSource.getConnection();

        try {
            con.setAutoCommit(false); //νŠΈλžœμž­μ…˜ μ‹œμž‘
            //λΉ„μ¦ˆλ‹ˆμŠ€ 둜직
            bizLogic(con, fromId, toId, money);
            con.commit(); //성곡 μ‹œ 컀밋

        } catch (Exception e) {
            con.rollback(); //μ‹€νŒ¨ μ‹œ λ‘€λ°±
            throw new IllegalStateException(e);

        } finally {
            release(con);

        }
    }
}

νŠΈλžœμž­μ…˜μ€ λΉ„μ¦ˆλ‹ˆμŠ€ 둜직이 μžˆλŠ” μ„œλΉ„μŠ€ κ³„μΈ΅μ—μ„œ μ‹œμž‘ν•˜λŠ” 것이 μ’‹λ‹€.
κ·ΈλŸ¬λ‚˜ λ¬Έμ œλŠ”, νŠΈλžœμž­μ…˜μ„ μ‚¬μš©ν•˜κΈ° μœ„ν•΄ javax.sql.DataSource, java.sql.Connection, java.sql.SQLException 같은 JDBC κΈ°μˆ μ— μ˜μ‘΄ν•΄μ•Ό ν•œλ‹€λŠ” 점이닀.
결과적으둜 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§λ³΄λ‹€ JDBCλ₯Ό μ‚¬μš©ν•΄μ„œ νŠΈλžœμž­μ…˜μ„ μ²˜λ¦¬ν•˜λŠ” μ½”λ“œκ°€ 더 λ§Žλ‹€. 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 JDBC 기술이 μ„žμ—¬ μžˆμ–΄μ„œ μœ μ§€λ³΄μˆ˜ν•˜κΈ° μ–΄λ ΅λ‹€.

νŠΈλžœμž­μ…˜ 문제

  • JDBC κ΅¬ν˜„ 기술이 μ„œλΉ„μŠ€ 계측에 λˆ„μˆ˜λ˜λŠ” 문제

    • κ΅¬ν˜„ κΈ°μˆ μ„ 변경해도 μ„œλΉ„μŠ€ 계측 μ½”λ“œλŠ” μ΅œλŒ€ν•œ μœ μ§€ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€. κ·Έλž˜μ„œ 데이터 μ ‘κ·Ό 계측에 JDBC μ½”λ“œλ₯Ό λ‹€ λͺ°μ•„λ‘λŠ” 것이닀. (데이터 μ ‘κ·Ό 계측은 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•˜λŠ” 것이 μ’‹λ‹€.)
    • νŠΈλžœμž­μ…˜μ„ μ μš©ν•˜λ©΄μ„œ κ²°κ΅­ μ„œλΉ„μŠ€ 계측에 JDBC κ΅¬ν˜„ 기술의 λˆ„μˆ˜κ°€ λ°œμƒν–ˆλ‹€.
  • νŠΈλžœμž­μ…˜ 동기화 문제

    • 같은 νŠΈλžœμž­μ…˜μ„ μœ μ§€ν•˜κΈ° μœ„ν•΄ 컀λ„₯μ…˜μ„ νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ•Ό ν•œλ‹€.
    • λ˜‘κ°™μ€ κΈ°λŠ₯도 νŠΈλžœμž­μ…˜μš© κΈ°λŠ₯κ³Ό νŠΈλžœμž­μ…˜μ„ μœ μ§€ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” κΈ°λŠ₯으둜 뢄리해야 ν•œλ‹€.
  • νŠΈλžœμž­μ…˜ 적용 반볡 문제

    • νŠΈλžœμž­μ…˜ 적용 μ½”λ“œλ₯Ό 보면 반볡이 λ§Žλ‹€. (try, catch, finally...)

μ˜ˆμ™Έ λˆ„μˆ˜ 문제

  • 데이터 μ ‘κ·Ό κ³„μΈ΅μ˜ JDBC κ΅¬ν˜„ 기술 μ˜ˆμ™Έκ°€ μ„œλΉ„μŠ€ κ³„μΈ΅μœΌλ‘œ μ „νŒŒλœλ‹€.

JDBC 반볡 문제

  • MemberRepository μ½”λ“œλŠ” μœ μ‚¬ν•œ μ½”λ“œμ˜ 반볡이 λ§Žλ‹€. (try, catch, finally...)
  • 컀λ„₯μ…˜μ„ μ—΄κ³  PreparedStatementλ₯Ό μ‚¬μš©ν•˜κ³ , κ²°κ³Όλ₯Ό λ§€ν•‘ν•˜κ³ ... μ‹€ν–‰ν•˜κ³  컀λ„₯μ…˜κ³Ό λ¦¬μ†ŒμŠ€λ₯Ό μ •λ¦¬ν•œλ‹€.

νŠΈλžœμž­μ…˜ 좔상화

κ΅¬ν˜„ κΈ°μˆ μ— λ”°λ₯Έ νŠΈλžœμž­μ…˜ μ‚¬μš©λ²•

  • JDBC: con.setAutoCommit(false)
  • JPA: transaction.begin()

νŠΈλžœμž­μ…˜ 좔상화 μΈν„°νŽ˜μ΄μŠ€

public interface TxManager {
   begin();
   commit();
   rollback();
}

TxManager μΈν„°νŽ˜μ΄μŠ€λ₯Ό 기반으둜 각각의 κΈ°μˆ μ— λ§žλŠ” κ΅¬ν˜„μ²΄λ₯Ό λ§Œλ“€λ©΄ λœλ‹€.

  • JdbcTxManager: JDBC νŠΈλžœμž­μ…˜ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” κ΅¬ν˜„μ²΄
  • JpaTxManager: JPA νŠΈλžœμž­μ…˜ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” κ΅¬ν˜„μ²΄

νŠΈλžœμž­μ…˜ 좔상화와 μ˜μ‘΄κ΄€κ³„

νŠΈλžœμž­μ…˜ 좔상화와 μ˜μ‘΄κ΄€κ³„

μ„œλΉ„μŠ€λŠ” νŠΉμ • νŠΈλžœμž­μ…˜μ— κΈ°μˆ μ— 직접 μ˜μ‘΄ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, TxManagerλΌλŠ” μΆ”μƒν™”λœ μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•œλ‹€. 이제 μ›ν•˜λŠ” κ΅¬ν˜„μ²΄λ₯Ό DIλ₯Ό 톡해 μ£Όμž…ν•˜λ©΄ λœλ‹€.

μŠ€ν”„λ§μ˜ νŠΈλžœμž­μ…˜ 좔상화

μš°λ¦¬λŠ” μŠ€ν”„λ§μ΄ μ œκ³΅ν•˜λŠ” νŠΈλžœμž­μ…˜ 좔상화 κΈ°μˆ μ„ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

μŠ€ν”„λ§μ˜ νŠΈλžœμž­μ…˜ 좔상화

μŠ€ν”„λ§μ˜ νŠΈλžœμž­μ…˜ 좔상화

μŠ€ν”„λ§ νŠΈλžœμž­μ…˜ μΆ”μƒν™”μ˜ 핡심은 PlatformTransactionManager μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.

PlatformTransactionManager μΈν„°νŽ˜μ΄μŠ€

public interface PlatformTransactionManager extends TransactionManager {

	TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
    
	void commit(TransactionStatus status) throws TransactionException;
	void rollback(TransactionStatus status) throws TransactionException;
}
  • getTransaction() : νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν•œλ‹€.
  • commit() : νŠΈλžœμž­μ…˜μ„ μ»€λ°‹ν•œλ‹€.
  • rollback() : νŠΈλžœμž­μ…˜μ„ λ‘€λ°±ν•œλ‹€.

νŠΈλžœμž­μ…˜ 동기화

μŠ€ν”„λ§μ΄ μ œκ³΅ν•˜λŠ” νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” 크게 2가지 역할을 ν•œλ‹€.

  • νŠΈλžœμž­μ…˜ 좔상화
  • λ¦¬μ†ŒμŠ€ 동기화
    νŠΈλžœμž­μ…˜μ„ μœ μ§€ν•˜λ €λ©΄ νŠΈλžœμž­μ…˜μ˜ μ‹œμž‘λΆ€ν„° λκΉŒμ§€ 같은 λ°μ΄ν„°λ² μ΄μŠ€ 컀λ„₯μ…˜μ„ μœ μ§€(동기화)ν•΄μ•Ό ν•œλ‹€.

νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €μ™€ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €

νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €μ™€ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €

μŠ€ν”„λ§μ€ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €λ₯Ό μ œκ³΅ν•œλ‹€. 이것은 ThreadLocal을 μ‚¬μš©ν•΄μ„œ 컀λ„₯μ…˜μ„ 동기화 ν•΄μ€€λ‹€. νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λŠ” λ‚΄λΆ€μ—μ„œ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €λ₯Ό μ‚¬μš©ν•œλ‹€.
컀λ„₯μ…˜μ΄ ν•„μš”ν•˜λ©΄ νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €λ₯Ό 톡해 μ–»μœΌλ©΄ λœλ‹€.

μ°Έκ³ 
μŠ€λ ˆλ“œ λ‘œμ»¬μ„ μ‚¬μš©ν•˜λ©΄ 각 μŠ€λ ˆλ“œλ§ˆλ‹€ λ³„λ„μ˜ μ €μž₯μ†Œκ°€ λΆ€μ—¬λœλ‹€. λ”°λΌμ„œ ν•΄λ‹Ή μŠ€λ ˆλ“œλ§Œ 데이터에 μ ‘κ·Όν•  수 μžˆλ‹€.

DataSourceUtils.getConnection()
DataSourceUtils.getConnection()λŠ” νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €κ°€ κ΄€λ¦¬ν•˜λŠ” 컀λ„₯μ…˜μ΄ 있으면 ν•΄λ‹Ή 컀λ„₯μ…˜μ„ λ°˜ν™˜ν•œλ‹€.
νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €κ°€ κ΄€λ¦¬ν•˜λŠ” 컀λ„₯μ…˜μ΄ μ—†λŠ” 경우 μƒˆλ‘œμš΄ 컀λ„₯μ…˜μ„ μƒμ„±ν•΄μ„œ λ°˜ν™˜ν•œλ‹€.

DataSourceUtils.releaseConnection()
DataSourceUtils.releaseConnection()을 μ‚¬μš©ν•˜λ©΄ 컀λ„₯μ…˜μ„ λ°”λ‘œ 닫지 μ•ŠλŠ”λ‹€.
νŠΈλžœμž­μ…˜μ„ μ‚¬μš©ν•˜κΈ° μœ„ν•΄ λ™κΈ°ν™”λœ 컀λ„₯μ…˜μ€ 닫지 μ•Šκ³  κ·ΈλŒ€λ‘œ μœ μ§€ν•΄μ€€λ‹€.
νŠΈλžœμž­μ…˜ 동기화 λ§€λ‹ˆμ €κ°€ κ΄€λ¦¬ν•˜λŠ” 컀λ„₯μ…˜μ΄ μ—†λŠ” 경우 ν•΄λ‹Ή 컀λ„₯μ…˜μ„ λ‹«λŠ”λ‹€.

νŠΈλžœμž­μ…˜ ν…œν”Œλ¦Ώ

νŠΈλžœμž­μ…˜μ„ μ‚¬μš©ν•˜λŠ” λ‘œμ§μ„ μ‚΄νŽ΄λ³΄λ©΄ 같은 νŒ¨ν„΄μ΄ λ°˜λ³΅λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.
νŠΈλžœμž­μ…˜μ„ μ‹œμž‘ν•˜κ³ , λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ μ‹€ν–‰ν•˜κ³ , μ„±κ³΅ν•˜λ©΄ μ»€λ°‹ν•˜κ³ , μ‹€νŒ¨ν•˜λ©΄ λ‘€λ°±ν•œλ‹€.
이런 ν˜•νƒœλŠ” 각각의 μ„œλΉ„μŠ€μ—μ„œ λ°˜λ³΅λœλ‹€. λ‹¬λΌμ§€λŠ” 뢀뢄은 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§λΏμ΄λ‹€.
이럴 λ•Œ ν…œν”Œλ¦Ώ 콜백 νŒ¨ν„΄μ„ ν™œμš©ν•˜λ©΄ 반볡 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

TransactionTemplate

public class TransactionTemplate {
   private PlatformTransactionManager transactionManager;
   public <T> T execute(TransactionCallback<T> action){..}
   void executeWithoutResult(Consumer<TransactionStatus> action){..}
}
  • execute() : 응닡 값이 μžˆμ„ λ•Œ μ‚¬μš©ν•œλ‹€.
  • executeWithoutResult() : 응닡 값이 없을 λ•Œ μ‚¬μš©ν•œλ‹€.

νŠΈλžœμž­μ…˜ AOP 이해

μ§€κΈˆκΉŒμ§€ νŠΈλžœμž­μ…˜ 좔상화도 λ„μž…ν•˜κ³ , 반볡적인 νŠΈλžœμž­μ…˜ λ‘œμ§μ„ ν•΄κ²°ν•˜κΈ° μœ„ν•΄ νŠΈλžœμž­μ…˜ ν…œν”Œλ¦Ώλ„ λ„μž…ν–ˆλ‹€. ν•˜μ§€λ§Œ μ„œλΉ„μŠ€ 계측에 μˆœμˆ˜ν•œ λΉ„μ¦ˆλ‹ˆμŠ€ 둜직만 λ‚¨κΈ΄λ‹€λŠ” λͺ©ν‘œλŠ” 아직 λ‹¬μ„±ν•˜μ§€ λͺ»ν–ˆλ‹€.
이럴 λ•Œ μŠ€ν”„λ§ AOPλ₯Ό 톡해 ν”„λ‘μ‹œλ₯Ό λ„μž…ν•˜λ©΄ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.


ν† ν”½ 1개 - System Call

μ‹œμŠ€ν…œ μ½œμ€ μ‚¬μš©μž κ³΅κ°„μ˜ μ½”λ“œμ—μ„œ 컀널 μ„œλΉ„μŠ€(ν•¨μˆ˜)λ₯Ό μš”μ²­ν•˜λŠ” 과정을 λ§ν•œλ‹€.

μ‹œμŠ€ν…œ 호좜(System Call)은 운영체제의 컀널이 μ œκ³΅ν•˜λŠ” μ„œλΉ„μŠ€μ— λŒ€ν•΄, μ‘μš© ν”„λ‘œκ·Έλž¨μ˜ μš”μ²­μ— 따라 컀널에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€.
보톡 Cλ‚˜ C++κ³Ό 같은 κ³ κΈ‰ μ–Έμ–΄λ‘œ μž‘μ„±λœ ν”„λ‘œκ·Έλž¨λ“€μ€ 직접 μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ‚¬μš©ν•  수 μ—†κΈ° λ•Œλ¬Έμ— κ³ κΈ‰ APIλ₯Ό 톡해 μ‹œμŠ€ν…œ ν˜ΈμΆœμ— μ ‘κ·Όν•˜κ²Œ ν•˜λŠ” 방법이닀.

컀널 콜(kernel call), 트랩(trap)이라고도 λΆ€λ₯΄λ©°, μ‘μš© ν”„λ‘œκ·Έλž¨μ΄ 컀널 κΈ°λŠ₯을 ν™œμš©ν•˜λ„λ‘ μ œκ³΅ν•œλ‹€.
μ‹œμŠ€ν…œ 호좜 라이브러리λ₯Ό 톡해 κ·Έ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆλ‹€.

μš°λ¦¬κ°€ κ°œλ°œν•˜λŠ” ν”„λ‘œκ·Έλž¨μ€ 일반적으둜 μœ μ € λͺ¨λ“œ(User Mode)μ—μ„œ μ‹€ν–‰ν•œλ‹€. ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 쀑 μΈν„°λŸ½νŠΈ(Interrupt)κ°€ λ°œμƒν•˜κ±°λ‚˜ μ‹œμŠ€ν…œ 콜(System Call)을 ν˜ΈμΆœν•˜κ²Œ 되면 컀널 λͺ¨λ“œ(Kernel Mode)둜 μ „ν™˜λœλ‹€.

컀널 λͺ¨λ“œλ‘œ μ „ν™˜λ  λ•Œμ—λŠ” μ‹€ν–‰ μ€‘μ΄λ˜ ν”„λ‘œκ·Έλž¨μ˜ ν˜„μž¬ CPU μƒνƒœλ₯Ό μ €μž₯ν•œλ‹€. 그리고 컀널이 μΈν„°λŸ½νŠΈλ‚˜ μ‹œμŠ€ν…œ μ½œμ„ 직접 μ²˜λ¦¬ν•œλ‹€. μ²˜λ¦¬κ°€ μ™„λ£Œλ˜λ©΄ μ€‘λ‹¨λλ˜ ν”„λ‘œκ·Έλž¨μ˜ CPU μƒνƒœλ₯Ό λ‹€μ‹œ λ³΅μ›ν•œλ‹€.

OS 컀널이 μ œκ³΅ν•˜λŠ” μ„œλΉ„μŠ€λ₯Ό ν”„λ‘œκ·Έλž¨μ΄ μ΄μš©ν•˜κ³  싢을 λ•Œ μ‹œμŠ€ν…œ μ½œμ„ μ΄μš©ν•œλ‹€. μ‹œμŠ€ν…œ 콜이 λ°œμƒν•˜λ©΄ ν•΄λ‹Ή 컀널 μ½”λ“œκ°€ 컀널 λͺ¨λ“œμ—μ„œ μ‹€ν–‰λœλ‹€.

ν•˜λ“œμ›¨μ–΄ ν˜Ήμ€ μ‹œμŠ€ν…œ κ΄€λ ¨ κΈ°λŠ₯은 μ–΄λ–€ ν”„λ‘œκ·Έλž¨μ΄λΌλ„ λ°˜λ“œμ‹œ μ‹œμŠ€ν…œ μ½œμ„ ν†΅ν•΄μ„œλ§Œ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
ν•˜μ§€λ§Œ μš°λ¦¬λŠ” κ°œλ°œν•  λ•Œ 직접 OS μ‹œμŠ€ν…œ μ½œμ„ μ‚¬μš©ν•œ 적이 μ—†λ‹€. κ·ΈλŸΌμ—λ„ μš°λ¦¬λŠ” μ§€κΈˆκΉŒμ§€ 파일 I/O, λ„€νŠΈμ›Œν¬ I/O, ν”„λ‘œμ„ΈμŠ€, μŠ€λ ˆλ“œ κ΄€λ ¨ μž‘μ—…μ„ 잘 ν•΄μ™”λ‹€.

이게 μ–΄λ–»κ²Œ κ°€λŠ₯ν–ˆλ˜ κ²ƒμΌκΉŒ?

μš°λ¦¬κ°€ μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° 언어듀이 μ‹œμŠ€ν…œ μ½œμ„ 포μž₯(wrapping)ν•˜μ—¬ κ°„μ ‘μ μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ„λ‘ μ œκ³΅ν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

Thread thread = new Thread();
thread.start();

μŠ€λ ˆλ“œλ₯Ό λ§Œλ“œλŠ” 것은 μ‹œμŠ€ν…œ μ½œμ„ ν•„μš”λ‘œ ν•˜λŠ” μž‘μ—…μ΄λ‹€. 그럼 μœ„ μ½”λ“œλŠ” μ–΄λ–»κ²Œ λ™μž‘ν• κΉŒ?

start() μ½”λ“œλ‘œ λ“€μ–΄κ°€ 보면 private native void start0(); μ½”λ“œλ₯Ό λ³Ό 수 μžˆλ‹€. 즉, Java Native Interfaceλ₯Ό 톡해 OS의 μ‹œμŠ€ν…œ μ½œμ„ ν˜ΈμΆœν•˜κ²Œ λ˜λŠ” 것이닀.

μ‹œμŠ€ν…œ 콜의 μ’…λ₯˜

  • ν”„λ‘œμ„ΈμŠ€ μ œμ–΄ (Process control)
  • 파일 관리 (File management)
  • μž₯치 관리 (Device management)
  • 정보 μœ μ§€ 관리 (Information maintenance)
  • 톡신 (Communications)
  • 보호 (Protection)

μ‹œμŠ€ν…œ μ½œμ€ μ–΄λ–»κ²Œ κ΅¬ν˜„ν• κΉŒ?

  • eax λ ˆμ§€μŠ€ν„°μ— μ‹œμŠ€ν…œ 콜 번호λ₯Ό λ„£κ³ ,
  • ebx λ ˆμ§€μŠ€ν„°μ—λŠ” μ‹œμŠ€ν…œ μ½œμ— ν•΄λ‹Ήν•˜λŠ” μΈμžκ°’μ„ λ„£κ³ ,
  • μ†Œν”„νŠΈμ›¨μ–΄ μΈν„°λŸ½νŠΈ λͺ…령을 ν˜ΈμΆœν•˜λ©΄μ„œ 0x80 값을 λ„˜κ²¨μ€Œ.
    mov eax, 1
    mov ebx, 0
    int 0x80 //μ†Œν”„νŠΈμ›¨μ–΄ μΈν„°λŸ½νŠΈ λͺ…λ Ή
    • CPUλŠ” μ‚¬μš©μž λͺ¨λ“œλ₯Ό 컀널 λͺ¨λ“œλ‘œ λ°”κΏ”μ€Œ.
    • IDT(Interrupt Descriptor Table)μ—μ„œ 0x80에 ν•΄λ‹Ήν•˜λŠ” μ£Όμ†Œ ν•¨μˆ˜λ₯Ό μ°Ύμ•„μ„œ 싀행함.
    • system_call() ν•¨μˆ˜μ—μ„œ eaxλ‘œλΆ€ν„° μ‹œμŠ€ν…œ 콜 번호λ₯Ό μ°Ύμ•„μ„œ, ν•΄λ‹Ή λ²ˆν˜Έμ— λ§žλŠ” μ‹œμŠ€ν…œ 콜 ν•¨μˆ˜λ‘œ 이동.
    • ν•΄λ‹Ή μ‹œμŠ€ν…œ 콜 ν•¨μˆ˜ μ‹€ν–‰ ν›„, λ‹€μ‹œ 컀널 λͺ¨λ“œμ—μ„œ μ‚¬μš©μž λͺ¨λ“œλ‘œ λ³€κ²½ν•˜κ³ , λ‹€μ‹œ ν•΄λ‹Ή ν”„λ‘œμ„ΈμŠ€μ˜ λ‹€μŒ μ½”λ“œλ₯Ό μ§„ν–‰ν•œλ‹€.

μ‹œμŠ€ν…œ 호좜

  • μš΄μ˜μ²΄μ œκ°€ μ œκ³΅ν•˜λŠ” μ„œλΉ„μŠ€μ— λŒ€ν•œ ν”„λ‘œκ·Έλž˜λ° μΈν„°νŽ˜μ΄μŠ€(interface)
    • ν•˜λ“œμ›¨μ–΄μ˜ μƒμ„Έν•œ λ™μž‘μ„ 좔상화 (ν”„λ‘œκ·Έλž˜λ° νŽΈμ˜μ„±)
    • 운영체제λ₯Ό ν†΅ν•΄μ„œλ§Œ ν•˜λ“œμ›¨μ–΄ μžμ›μ— μ ‘κ·Ό (보호)
  • 일반적으둜 C, C++ μ–Έμ–΄λ‘œ μž‘μ„±λ˜μ–΄ ν•¨μˆ˜ 호좜 ν˜•νƒœλ‘œ 제곡

Application Program Interface(API)

  • μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ ν™œμš©ν•˜μ—¬ 높은 μˆ˜μ€€μ˜ ν•¨μˆ˜ 집합을 제곡
  • 일반적인 API의 예
    • Win32 API, POSIX API(UNIX, Linux), Java API
  • μ‘μš© ν”„λ‘œκ·Έλž˜λ¨Έλ“€μ΄ μ‹€μ œλ‘œ μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° μΈν„°νŽ˜μ΄μŠ€
    • ν”„λ‘œκ·Έλž¨μ˜ ν˜Έν™˜μ„±μ΄ λ†’λ‹€.
    • μ‹œμŠ€ν…œ 호좜의 μ‚¬μš©μ΄ λ³΅μž‘ν•˜κ±°λ‚˜ μ–΄λ €μš΄ κ²½μš°κ°€ μžˆλ‹€.

ν•„μš”ν•œ κΈ°λŠ₯μ΄λ‚˜ μ‹œμŠ€ν…œ ν™˜κ²½μ— 따라 μ‹œμŠ€ν…œ 콜이 λ°œμƒν•  λ•Œ μ’€ 더 λ§Žμ€ 정보가 ν•„μš”ν•  수 μžˆλ‹€. μ΄λŸ¬ν•œ 정보가 λ‹΄κΈ΄ λ§€κ°œλ³€μˆ˜λ₯Ό μš΄μ˜μ²΄μ œμ— μ „λ‹¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒκ³Ό 같은 방법이 μžˆλ‹€.

  1. λ§€κ°œλ³€μˆ˜λ₯Ό CPU λ ˆμ§€μŠ€ν„° 내에 μ „λ‹¬ν•œλ‹€.
    이 경우, λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜κ°€ CPU λ‚΄μ˜ 총 λ ˆμ§€μŠ€ν„° κ°œμˆ˜λ³΄λ‹€ λ§Žμ„ 수 μžˆλ‹€.

  2. μœ„μ™€ 같은 경우, λ§€κ°œλ³€μˆ˜λ₯Ό λ©”λͺ¨λ¦¬μ— μ €μž₯ν•˜κ³  λ©”λͺ¨λ¦¬μ˜ μ£Όμ†Œκ°€ λ ˆμ§€μŠ€ν„°μ— μ „λ‹¬λœλ‹€.

  3. λ§€κ°œλ³€μˆ˜λŠ” ν”„λ‘œκ·Έλž¨μ— μ˜ν•΄ μŠ€νƒ(stack)으둜 전달(push)될 μˆ˜λ„ μžˆλ‹€.
    2, 3번 λ°©λ²•μ˜ 경우 μ „λ‹¬λ˜λŠ” λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜λ‚˜ 길이에 μ œν•œμ΄ μ—†κΈ° λ•Œλ¬Έμ— λͺ‡λͺ‡ μš΄μ˜μ²΄μ œμ—μ„œ μ„ ν˜Έν•˜λŠ” 방식이닀.


참고 자료

  1. DR-Kim, β€œ[OS] μ‹œμŠ€ν…œ 호좜(System Calls)”, https://dar0m.tistory.com/264

  2. μ‰¬μš΄ μ½”λ“œ, β€œμΈν„°λŸ½νŠΈμ™€ μ‹œμŠ€ν…œ μ½œμ„ μ„€λͺ…ν•©λ‹ˆλ‹€!”, https://youtu.be/v30ilCpITnY

  3. Young Hyun Bae, β€œ03-3 μ‹œμŠ€ν…œν˜ΈμΆœκ³Ό λΌμ΄λΈŒλŸ¬λ¦¬β€, https://youtu.be/bjGIf_AKtAc

  4. 패슀트캠퍼슀, β€œμ»΄ν“¨ν„°κ³΅ν•™ μ˜¬μΈμ›νŒ¨ν‚€μ§€ - 사스템 프로그ᄅᅒ망, 사스템콜ᄀα…ͺ API”, https://youtu.be/SuovfEG9XZw


μ½”ν…Œ 1문제


내일 온라인으둜 λ°œν‘œν•  κ±° μ€€λΉ„!!

profile
김뉴비

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보