씨언어를 사용하여 화면에 결과를 출력할 때 printf를 사용한 경험이 있을 것이다. printf를 사용하기 위해 #include <stdio.h>라는 헤더 파일을 선언해야 했다.
이때, 헤더 파일에는 함수가 있다는 정보만 선언되어 있고 실제 코드는 "라이브러리 파일"에 있다. 즉, 헤더 파일과 라이브러리 파일 둘 다 있어야 printf 함수를 실행할 수 있다는 것이다.
자세하게 보자면,
- 헤더 파일[ stdio.h ] 에는 라이브러리 함수의 선언만 있다. [ extern printf(); ]
- /usr/include 혹은 /usr/include/sys 에 미리 정의된 헤더파일들이 있음 (ex) stdio.h
- 실제 함수의 정의(디테일한 내용)는 라이브러리 파일에 있다. ex) printf의 함수가 어떤 일을 하는지, 함수의 argument 및 return 타입에 대한 것은 라이브러리 파일 안에 있다.
그럼 이 라이브러리와 헤더 파일은 따로 존재하는데 프로그램이 실행되기 위해서 어떠한 동작을 할까?
이 과정을 자세하게 살펴보자.
컴파일과 링킹 과정
[source file] ➡️ “컴파일” ➡️ [ object file + 라이브러리 파일] ➡️ “링크”
➡️[executable file + 공유 라이브러리] ➡️ “로더” ➡️ 메모리에 적재
- (1) 소스 파일 (driver.c) 에 대응되는 오브젝트 파일(driver.o)이 있다. 이때 각종 오브젝트 파일들과 라이브러리 파일(libc.a)이 link된다. ⇒ 이들에 대한 실행 파일을 만드려면 linking의 과정이 필요하다.
- (2) 링크를 통해 실행 파일(executable file)이 있다. 로더를 통해 메모리에 적재되어 프로그램이 실행되는데 이때 공유 라이브러리를 dynamic linking을 하는 과정이 있다.
이 두 가지 라이브러리에 대해서 자세하게 살펴보자.
라이브러리 종류
(1) static 라이브러리
→ [ linking ] 을 할 때 static linking을 한다.
컴파일 및 링크 시 실행 파일 내에 라이브러리 함수가 포함되어 만들어짐
[ static linking ]
- static 라이브러리가 프로그램의 실행 파일 코드에 포함됨(static library)
- 실행 파일의 크기가 커짐
- ex) a.o, b.o, c.o라는 오브젝트 파일 안에 각각 static 라이브러리가 include되므로 실행파일의 크기가 커짐
- 동일한 라이브러리를 각각의 프로세스가 메모리에 올리므로 메모리 낭비가 된다.
- ex) a.o, b.o, c.o라는 것에 각각 10k만큼의 printf 함수를 쓴다면 3개에 각각 프로세스가 파일 안에 있으므로 30k를 쓰므로 메모리 낭비
static 라이브러리의 장점
이미 실행파일을 만들었을 때 이미 포함되어 있기 때문에 실행할 때 빠르다.
static 라이브러리의 단점
static 라이브러리가 실행 파일에 포함되는 형식이므로 실행파일의 크기가 커진다.
각각의 프로세스가 메모리에 올라가므로 메모리 낭비가 있다.
(2) shared 라이브러리 (공유 라이브러리)
→ [ loading ] 될 때 dynamic linking ( = 실행 파일 실제로 실행시키기 위해 메모리에 로드하는 과정에서 실행될 때 shared library가 실행파일과 같이 include가 되어 실행된다 )
*여기서 linking이라는 단어는 링커와 다른 부분이다. 그냥 연결한다라는 의미
- 컴파일 및 링크 시 실행 파일 내에 라이브러리 함수가 포함되지 않고 위치 정보만 매핑 해놓음
- 실행 시 호출되는 시점에 라이브러리 파일로부터 메모리에 적재(로딩)되어 실행
- 로딩된 라이브러리는 다른 프로세스들이 사용할 수 있음 = “shared”
[dynamic linking]
- 라이브러리가 실행시 link됨 (= 공유 라이브러리, shared library)
- 해당 라이브러리를 쓰는 프로세스가 3개가 있다면 하나의 메모리에 올라간 공유 라이브러리를 공유해서 쓰는 것이기 때문에(한 번만 메모리 로딩)
- 실행 파일에는 라이브러리 자체가 포함되는 것이 아니라 라이브러리의 위치를 찾기 위한 간단한 코드만 둔다.
- *실행 파일에는 라이브러리가 포함되지 않아서 오류 ?
- ex) a.out파일에서 라이브러리 위치를 찾아간다. → 만약 그 위치에 라이브러리가 없다면 오류가 나고 라이브러리가 있다면 정상적 실행한다.
- 라이브러리가 이미 메모리에 있으면 그 루틴의 주소로 가고 없으면 디스크에서 읽어옴
공유 라이브러리의 장점
(1) 메모리 절약
한 군데 메모리에만 로딩이 되어 있으면 여러 개의 프로세스가 동시에 그것을 사용할 수 있기 때문에 메모리 공간을 차지하거나 그렇지 않는다.(메모리 공간 절약)
(2) 많은 프로그램이 동일 라이브러리를 호출할 때 한 카피만 메모리에 적재
큰 프로젝트를 할 때 효율적으로 작업이 필요하다면 각 파일에 공통모듈이 있어서 그 부분이 많을 수록 shared library를 사용한다. (많이 알려진 라이브러리 printf 같은 경우는 static 라이브러리를 사용한다
공유 라이브러리의 단점
(1) 실행 파일 뿐 아니라 동일한 라이브러리 파일이 있어야 소프트웨어 실행이 가능하다.
(2) 실행 시점에서 로딩이 되므로 속도가 약간 느려질 수 있다.
(3) 컴파일 시 복잡한 초기 bookkeeping 작업으로 느림
참조하는 것을 실제로 끌어들이는 것이 아니라 위치를 참조하는 방식이므로 이 위치를 체크해야 하는 부분이 있으므로 상대적으로 느릴 수 있다.
시스템 소프트 웨어 이해
'CS > 컴퓨터 시스템' 카테고리의 다른 글
Chap 5. 컴퓨터 시스템 구조 (0) | 2022.05.19 |
---|---|
Chap 4. 운영체제란? (0) | 2022.05.18 |
Chap 3 - 2. 부분 컴파일 (0) | 2022.05.13 |
Chap 3. 고급 언어의 기계어 변환 및 실행 (0) | 2022.05.12 |
Chap 1. System Software와 ISA (0) | 2022.03.24 |