왜 운영체제, 시스템 프로그래밍을 공부해야 하는가

Eddy·2022년 8월 9일
64

첫 출근 날. 업무용 소프트웨어를 이것저것 세팅하고 있었다. 무슨 업무를 하게 될까? 은근 긴장도 되고 설레기도 했다.

그러다 나를 본 CTO님은, 아 오셨군요, 하면서 갑자기 뭔가를 무거운 것을 가져오더니 책상에 쿵 내려놓았다.

두꺼운 책 2권이었다. 둘 다 '시스템 프로그래밍' 책이었다. '시스템 프로그래밍...? 시스템 프로그래밍이 뭐지?' 순간 내 머릿속에 떠오른 생각이었다.

'자, 이제 이거 스터디를 하시면 돼요.'

아... 내가 처음 해야할 일은 운영체제, 리눅스 시스템 프로그래밍 공부였다.

시스템 프로그래밍이란 무엇인가?

시스템 프로그래밍이란 무엇일까? 내가 찾아보고 이해한 정의는 이렇다.

'어플리케이션 소프트웨어'가 아닌 '시스템 소프트웨어'를 프로그래밍하는 게 시스템 프로그래밍이다. 애플리케이션 프로그래밍의 반대로 시스템 프로그래밍을 이해해보자는 말이다.

우리는 보통 애플리케이션 개발로 프로그래밍에 입문한다. 그래서 애플리케이션이 어떤 건지는 안다.

어플리케이션은 일반 사용자들이 사용할 수 있는 소프트웨어다. 자바, 파이썬, 자바스크립트 같은 고수준 언어를 사용해서 프로그래밍한다.

하지만 여러분은 실제로 이런 애플리케이션을 만들면서, 직접 프로세스를 생성하거나, 디스크에 있는 파일을 열거나, 키보드 장치에서 데이터를 읽는 코드를 쓴 적이 있는가? 아마 없을 것이다.

그렇지만 당연히 소프트웨어는 하드웨어 자원을 사용해야 한다. 그럼 어떻게 된 것이냐? 이 갭은 시스템 소프트웨어가 메꿔준다.

시스템 소프트웨어는 어플리케이션 소프트웨어가 하드웨어와 저수준 기능을 사용할 수 있도록 도와주는 소프트웨어다.

보통 커널에서 제공하는 저수준 기능을 활용해서, 다른 소프트웨어에게 좀 더 추상화되고 편리한 기능을 제공한다.

커널이 제공하는 API는 추상화가 많이 되어있지 않은 저수준의 인터페이스다. 직접 사용해서 원하는 프로그램을 만드는 게 상당히 어렵다.

그래서 보통 애플리케이션 프로그래밍에서는 커널을 직접 호출하지 않는다. 대신 컴파일러처럼 시스템 호출을 활용하는 다른 소프트웨어를 사용한다.

시스템 소프트웨어는 자신이 커널을 직접 호출하고 하드웨어 자원을 조작한다. 다른 프로그램에게는 그 기능을 쉽게 사용할 수 있도록 추상화(단순화)된 인터페이스를 제공한다.

아파치 같은 웹서버, Vim/Emacs 같은 코드 에디터, 커맨드라인 인터페이스를 제공하는 쉘, 각 언어의 컴파일러, 장치 드라이버, mySQL 같은 DB 관리 시스템까지.

이런 것들이 직접 하드웨어와 운영체제를 다루면서, 조금 더 고수준의 어플리케이션에게 기능을 제공하는 시스템 소프트웨어다. (넓은 의미의 시스템 소프트웨어는 운영체제까지 포함한다.)

왜 시스템 프로그래밍을 배워야 하는가?

프로그램을 실행한다는 건 어떤 의미일까?

보통 사용자에게는 그냥 '더블 클릭'일 뿐이다. 하지만 실제로 기계 수준까지 내려가면, 그 더블 클릭 하나에 엄청나게 복잡한 동작들이 숨어있다.

하지만 우리는 그 모든 걸 몰라도 프로그램을 실행할 수 있다.

왜냐하면 '추상화'된 시스템을 쓰기 때문이다. 추상화는 컴퓨터 공학의 근본 중의 근본이다. 쉽게 말해 복잡한 기계의 복잡한 작동 원리를 숨기고 단순한 방법으로 사용할 수 있게 만든다는 뜻이다.

시스템을 추상화하면, 세부 사항을 모르고도 시스템을 사용할 수 있다. 컴퓨터 공학은 CPU부터 웹 브라우저까지 '추상화'라는 층을 쌓아서 어려운 일을 쉽게 만든다.

하지만 반대로도 생각해보자. 꼭 좋기만 한 건 아니지 않을까?

추상화된 시스템만 사용하면 우리는 내부의 동작 원리를 알 수 없다.

물론 내부의 동작 원리와 세부적인 구현은 복잡하다.

하지만 추상화된 경계면 아래를 이해한 프로그래머는 새로운 능력을 갖게 된다. 상황에 맞게 최적화된 맞춤형 코드를 쓸 수 있고, 추상화된 시스템이 제대로 돌아가지 않을 때 문제를 해결할 수 있다.

'시스템 프로그래밍'은 보통 웹, 앱 개발자들이 잘 건드리지 않는 추상화의 아랫층에 존재한다.

하지만 시스템 프로그래밍을 하려면 하드웨어와 커널이라는 저수준 시스템을 이해해야 한다. 덕분에 시스템 프로그래밍을 이해하면 더 효율적인 프로그래밍을 할 수 있고, 고수준 언어에서 프로그래밍할 때는 도대체 이해할 수 없는 버그들을 해결할 수 있게 된다.

예를 들어 보자. 네트워크 통신을 하는 코드를 작성했. "Too many open files” 이라는 에러가 떴다. 무슨 소리지? 저수준 시스템에 대해 이해하지 못한다면 머리만 아플 것이다.

하지만 만약 시스템 프로그래밍을 배웠다면?

리눅스에서는 통신 인터페이스도 파일의 형태이기 때문에, 네트워크 통신을 할 때 파일을 여는 시스템 콜을 사용한다는 것을 알고 있을 것이다. 리눅스의 프로세스에서 열 수 있는 파일의 최대 갯수는 기본 1024개로 정해져있다는 것도 알고 있을 것이다.

아랫층을 이해한 개발자는 문제를 좀 더 쉽게 해결할 수 있다.

그런 의미에서 많은 개발자들이 실력있는 개발자가 되려면 반드시 갖춰야할 기본기로 '운영체제'와 '컴퓨터 구조'에 대한 이해를 꼽는다. 그리고 시스템 프로그래밍이란 운영체제나 하드웨어(컴퓨터 구조)와 굉장히 밀접한 연관이 있다. 운영체제가 제공하는 서비스를 직접 사용하는 프로그래밍이니까.

소프트웨어 세계의 아랫층으로

나도 비전공자다. 이번에서야 '시스템 프로그래밍'이 뭔지 제대로 알았다. 물론 운영체제를 공부한 적은 있지만, 소프트웨어 세계의 복잡하고 심오한 아랫층은 여전히 두려운 장소다.

하지만 업무로 기본기 공부를 하게 된 이상, 한번 깊이있게 제대로 파보려고 한다.

지금 30% 정도 진도를 나갔다. 내용을 정리하기도 하지만, 결국엔 내 언어로 풀어보면서 설명을 했을 때 가장 잘 이해가 된다고 생각한다. 내가 이해한 운영체제와 시스템 콜의 세계를 시리즈로 포스팅해보려 한다.

주로 읽고 있는 책은 다음과 같다.

📕 운영체제 10판, Abraham Silberschatz, Peter Baer Galvin, Greg Gagne 저/박민규 역
📕 Operating Systems: Three Easy Pieces, Andrea Arpaci-Dusseau and Remzi Arpaci-Dusseau
📕 리눅스 시스템 프로그래밍, Robert Love
📕 시스템 프로그래밍: 리눅스 & 유닉스, 이종원

비록 전부 다 상당히 딱딱하고 두꺼운 교과서 책이긴 하지만, 나도 잘 모르는만큼 이 글에서는 엄밀함보다는 직관적이고 쉽고 재미있는 설명에 초점을 맞춘다.

이 시리즈를 읽고 나면 여러분도 딱딱한 교과서를 읽는 것보다는 훨씬 쉽게 전반적인 개념을 잡을 수 있을 것이다.

먼저 시스템 프로그래밍을 이해하기 위한 기본 개념들부터 시작한다.

profile
개발 지식을 쉽고 재미있게 설명해보자. ▶️ www.youtube.com/@simple-eddy

8개의 댓글

comment-user-thumbnail
2022년 8월 10일

안녕하세요, Eddy님. 올려주신 글 재밌게 읽었습니다. 더불어 저희는 쉽고 재밌는 IT 인사이트를 공유하는 요즘IT라는 매체입니다. 작가님께 기고 관련 제안을 드리고 싶어 댓글을 남겨봅니다. 괜찮으시다면 yozm_help@wishket.com으로 연락주시면, 기고 관련 내용을 안내드리고자 합니다. 그럼 살펴주신 후, 회신 부탁드립니다. 좋은 하루 보내세요 :)

답글 달기
comment-user-thumbnail
2022년 8월 12일

좋은 글이네용 ^^ ㅎㅎ 잘 읽었습니당

1개의 답글
comment-user-thumbnail
2022년 8월 19일

eddy님의 글은 궁금하거나 아쉬웠던 부분의 가려움을 긁어주는 듯하네요!! 깊이 있게 알아가는 재미가 있군요 ㅎㅎ 좋은 글 감사합니다!!

1개의 답글
comment-user-thumbnail
2022년 8월 25일

CTO 에 OS 책을 읽으라는 미션을 준다고 하셔서 무슨 일을 하시는지 궁금해요!

답글 달기
comment-user-thumbnail
2022년 11월 26일

학부생인데 시스템 프로그래밍을 왜 배우나 궁금했어요. 재밌게 읽고갑니다 ㅎㅎ

답글 달기
comment-user-thumbnail
2022년 12월 25일

흥미있게 읽었습니다.

답글 달기