소개 

리눅스 시스템 프로그래밍(:12)관련 온라인 북을 만들기 위해서 생성한 위키(:12)페이지로, 문서는 다음과 같은 성격을 가진다.
  • 난이도 시스템 프로그래밍 초/중급
  • 대상 C(:12) 프로그래밍 입문과정을 거친자. 리눅스 환경에서의 C 프로그래밍과 연결된다. Linux 운영체제(:12)를 다룰 수 있는자. 리눅스 시스템 프로그래밍 입문자
  • 목표 리눅스 운영체제(:12)의 이해 리눅스 시스템 프로그래밍의 이해 C언어를 통한 리눅스 시스템 제어
  • 흥미위주가 아닌 낮은 수준에서 리눅스(:12) 시스템을 이해시키는데 주력한다.
문서구조는 다음과 같다.
  • 장,절,소절 의 3단계 깊이를 가진다.
  • 설명을 위한 도입부와 본문 정리를 위한 결론의 3부분으로 이루어진다.
    • 도입부는 A4지 반장 내외로 3문단 이내로 한다.
    • 본문은 문단단위로 이루어지며, 설명,잠깐,코드,그림의 4가지 구성요소를 가진다. 잠깐은 간략하게 짚고넘어갈 수 있는 팁수준의 내용을 담는다.
    • 결론은 요점정리와 문제출제로 한다. 


문서 프로젝트

경로제목
Ch01_IntroJoinc와 함께하는 리눅스 시스템 프로그래밍 : 1장 소개
Ch02_BeginningJoinC와 함께하는 리눅스 시스템 프로그래밍 2장 시작하기
Index리눅스 시템 프로그래밍 : 목차정리
ch03_EnvJoinc와 함께하는 리눅스 시스템 프로그래밍 3장 입력과 출력
ch04_UserJoinc와 함께하는 리눅스 시스템 프로그래밍 4장 - 유저 환경
ch05_ProcessJoinc와 함께하는 리눅스 시스템 프로그래밍 5장 프로세스
ch06_Signal리눅스 시스템 프로그래밍 6장 - Signal
ch07_Thread리눅스 시스템 프로그램밍 7장 쓰레드
ch08_IPC리눅스 시스템 프로그래밍 8장 IPC
ch09_Time리눅스 시스템 프로그래밍 9장 - 시간


1 소개 

1.1 리눅스를 접한게 언제 였더라 

리눅스를 본격적으로 접한게 1998년이였던 것으로 기억된다. 알짜 RedHat 5.3 인가 하는 RedHat(:12)의 한글판 버젼이 왠일로꽤 세인의 이목을 집중시켰던 적이 있었는데, 서점에 꽂혀있는걸 보고 냉큼 구입해서 집에 있는 486 컴퓨터에 설치했다. 그게 인연이 되어서 2007년 10월 지금에 이르렀다.

그때를 생각해보면, 리눅스에 유독 열광했던거 같다. 지금 생각해보면 단순함의 극치를 달리던 window:::maker(:12)가 그때는 왜 그리 멋져보였는지 모르겠다. 아이콘바꾸고 배경화면 바꾸고, 메뉴바꾸는 것만으로 몇날 몇일을 보냈던거 같다. 그러다가 IRC(:12)를 알게 되고, 다시 linux 채널에 들어가서 시간이 가는줄 모르고 리눅스 관련 이야기에 열중을 했다.

대학생활을 하긴 했지만 전공에 관심도 없었고, 그렇다고 잘 놀지도 못했었다. 뭔가 새로운 것이 필요했었는데, 그 때 리눅스가 나타난 것이라고 해야 할려나 싶다. 지금 생각해 보면 불행이기도 하고 다행이기도 한거 같다. 리눅스 대신에 여자에게 좀 관심을 가졌더라면, 지금은 좀더 밝은 세상에서 살고 있지 않을까라는 아쉬운 생각이 들기도 하는 반면, 그나마 리눅스에라도 관심을 가져서 굶지않고 살지라는 생각도 들고.

1.2 C 언어 

리눅스에 어느정도 익숙해졌을 무렵, 접한 언어가 php(:12) 였다. 결과가 눈에 바로 보이는게 재미있기도 하고 거기에 때마침 인터넷 벤쳐열풍이 불어 닥치던 때라서, 역시 밤낮을 가리지 않고 php를 가지고 놀았다. 지금 생각해보면 php를 이용해서 무언가를 학습하기 보다는 단지 아주 재미있는 장난감 정도로 생각을 했었던거 같다. 웹프로그래밍을 통해서 프로그래밍 세계에 발을 들여놓은 셈이다.

Linux를 접하고 php를 가지고 놀던 처음 1년 정도의 시기가 아마도 내가 무엇엔가 하나에 집중을 한 거의 유일한 시기가 아니였나 싶다. 그 뒤로 지금까지 어떤종류의 일이 되었던지 그때 처럼 집중을 했던 적은 없었던거 같다.

그러다가 C(:12)언어를 접하게 되었다. 교양과목으로 전산을 했던지라 hello world 정도는 출력할 줄 알았지만 hello world를 출력하는게 전부였던 때였다. 사실 C언어는 php에 비하자면 절대 재미있는 언어가 아니다. 그렇다고 전공이 이쪽 계통이라서 언어에 대한 개념이 있었던 것도 아니니, C언어의 필요성을 느꼇을 리도 없고 - 내 전공은 원자력 공학이다 -.

그냥 회사에서 php 가지고 이것저것 만들고 있는데, 어느날 php만으로는 모든걸 할 수 없다는 것을 깨닫게 되었다. 당시 php가지고 하던일이 웹메일 시스템 만들기였다. smtp(:12) 서버로 부터 메일을 받으면 이것을 디코딩하고 분류해서 Mysql(:12) 디비에 집어 넣는 일을 하는 시스템이였다. 뭐 기능을 구현하는 자체는 큰 무리는 없었는데, 디코딩에 너무 많은 시간이 걸린다는게 문제였다. 그때 php 버전이 3.0이였는데, php만을 가지고는 도저히 어떻게 시간을 줄일 수 있는 방법이 없는 거였다.

그래서 찾아낸게 C 언어였다. C 언어로 디코딩하는 부분만 구현해서, 테스트를 해봤더니 - 잘 기억은 나지 않지만 - 대략 5-10배 정도의 성능의 차이가 생기는 거였다. 그뒤로 코어의 진행은 C로 하게 되고, 지금까지 쭉 이어오고 있다. 현재는 C,C++ 언어를 주력으로 사용하고 php, perl 을 보조언어로 사용하고 있다.

1.3 시스템 프로그래밍을 다루게 되다. 

이렇게 해서 C 언어를 사용하게 되었다. 꽤나 어려울줄 알았는데, 왠걸 ? php와 문법도 비슷하고 별거 아니네, 라고 만만하게 보고 프로젝트에 C를 사용했는데....

지금도 그때 일이 생각 날 정도로 엄청난 고생을 했었다. 개고생을 하고나서 터득한 것은
  1. 언어에 있어서 문법은 중요한게 아니다.
  2. 중요한것은 언어가 다루는 환경이다.
라는 두가지 명제다. 이 두가지 명제를 몸으로 구르면서 터득한 거다.

문법 그건 아무것도 아니었다. 문법만 익히는 것은 초등학생 데려다 놓고 대충해도 한달이면 충분하다. 문제는 환경이다. 리눅스 시스템을 모르고 C 를 이용한 시스템 프로그래밍에 멋도 모르고 뛰어들었으니, 프로그램이 제대로 돌아갈리가 없다.

1.4 시스템 프로그래밍의 중요성을 깨닫다 

sadsense나름 개고생 하고나서, 약간 정신을 차리게 된 나는 정식으로 유닉스 시스템 프로그래밍에 대해서 공부를 시작했다. 그래봤자 독학이긴 하지만 꾸준히 한 덕택에 지금은 그럭저럭 필요한 프로그램 만들고, 분석할 수 있는 수준에 이르렀다. 이 과정에서 터득한 것이라면 시스템 프로그래밍의 중요성이다.

시스템 프로그래밍의 중요성에 대해서 얘기하고자 하지만, 현실에서는 시스템 프로그래밍 기술이 정말 중요한가 ? 라는 얘기를 듣곤한다. 프로그램을 만드는 프로그램을 이용해서 프로그램을 만드는 세상인데, 굳이 별로 재미도 없어보이는시스템 프로그래밍쪽을 공부해야 하느냐란 것이다. 훌륭한 Visual 개발툴과 잘 만들어진 라이브러리(:12)와 컴포넌트 기타 저작툴들이 널려있다.

이론상으로는 그럴듯 하다. 실제로 그런세계가 올지도 모른다. 컴퓨터에게 은행업무를 효율적으로 하기 위한 고객관리 프로그램이 필요하거든 한번 만들어봐라고 하고 몇가지 조건만 주면 그럴듯한 프로그램을 만들어내는 시대가 올지도 모른다.

그러나 (프로그래머의 입장에서는)다행스럽게도 지금의 컴퓨터는 산업전반에서 요구하는 모든 종류의 요청에 대해서 뚝딱하고 프로그램을 만들어낼 만큼 똑똑하지 못하다. 조금씩 인간이 개입하는 여지가 줄어들기는 하겠지만 당분간은 말로만으로 프로그램이 생성되어서, 프로그래머가 필요없는 세상은 오지 않을 것 같다.

결국 컴퓨터가 자동으로 할 수 없는 것은 인간이 책임질 수 밖에 없다. 이러한 영역이 주로 시스템 프로그래밍영역이 된다. 메뉴, 창, 버튼, 입력상자의 배치와 같은 프로그램의 외형은 컴퓨터가 자동으로 해낼 수 있지만 그 밑단의 시스템영역에서 이루어지는 데이터의 저장, 다중작업, 데이터 통신과 같은 일들은 경험있는 프로그래머가 반드시 필요하다. 여기에 덧하여 최적화라는 컴퓨터가 자동으로 수행할 수 없는 영역도 있다. 최적화라는 것은 프로그램의 성능을 좀더 높이기 위해서 시스템의 자원 사용을 최적화 하는 일련의 작업들이다. 메모리를 어떻게 사용할 것인지, 프로그램간에 데이터 통신은 어떻게 할건지, 대량의 데이터를 병렬처리 하기 위해서 어떤 시스템 통신 모델을 사용할 건지에 따라서 수십% 혹은 수백 %의 성능의 차이가 날 수 있는데, 이런 일은 자동화가 불가능한 영역이다. 역시 시스템에 대한 지식을 가진 경험있는 시스템 프로그래머가 필요하다.

결론은 이렇다. 아주 간단한 프로그램이 아닌한은 제대로 돌아가는 프로그램을 만들고자 한다면, 혹은 취미로 프로그램을 작성하고자 하는 생각 이 아니라면 시스템 프로그래밍은 선택사항이 아닌 필수 사항이다.

1.5 일반적인 프로그래밍 학습 과정 

공부에는 정도라는게 없다고 한다. 그럴듯도 하지만 선배들의 경험에 따른 더 좋은 방법이라는 것은 존재한다. 다행히도 프로그래밍을 하려는 여러분은 아무도 발을 내딛은 적이 없는 오지를 횡당하는게 아니다. 여러분이 가고자 하는 길을 많은 선배들이 앞서서 갔으니, 그들의 경험을 따를 필요가 있다.

그 경험에 의하자면 대략적인 프로그래밍 학습과정은 다음과 같다.
  1. 언어를 익힌다.
    perl, python, java, C++, C 등의 다양한 언어가 있다. 이중 하나의 언어를 선택한다. 여기에서는 C를 선택하도록 할 것이다. 일반적인 언어의 문법과 특징을 익히는데에는 한달이면 충분할 것이다. 그 이상 시간을 끄는 것은 낭비라고 생각된다.
  2. 시스템 프로그래밍을 한다. 우리가 하고자 하는 거다.
  3. 네트워크:::프로그래밍(:12)을 한다. 모든 컴퓨터가 인터넷(:12)에 연결된 세상에 살고 있으니, 네트워크 프로그래밍은 필수라고 할 수 있다.
  4. 시스템 프로그래밍을 한다. 네트워크 프로그래밍을 하다보면, 좀더 깊은 수준에서의 시스템 프로그래밍 기술이 필요하다는 걸 느끼게 될 것이다. 기존에 배웠던 시스템 프로그래밍을 좀더 깊은 수준에서 공부하게 된다.
  5. 자료구조(:12)와 알고리즘(:12)
    컴퓨터는 데이터를 처리하는 일을 한다. 그러므로 고수준의 프로그램을 작성하기 위해서는 데이터(자료)를 어떻게 구조화 하고, 어떤 알고리즘(:12)을 이용해서 효과적으로 처리해야 할지를 알고 있어야 한다.
  6. 응용 이제 게임을 하던지, 보안관련 프로그램을 작성하던지 혹은 데이터 베이스 관련일을 하던지 응용하는 일만 남아 있다. 시스템 프로그래밍과 네트워크 프로그래밍은 앞으로 나아가기 위한 초석이라고 보면 될것이다. 

이 방식의 단점이라면 고리타분하다는 점일 거다. 많은 사람들은 눈에 보이는 것을 좋아한다. 하지만 나중에 고생하고 싶지않다면, 제대로된 기반하에서 더 멀리보고 더 많은 것을 해보고 싶다면 위의 과정을 차근히 밟아나가길 바란다.

2 리눅스 시스템 프로그래밍 

2.1 운영체제와 시스템 프로그래밍 

시스템 프로그래밍이란 컴퓨터 시스템을 다루는 프로그래밍을 의미한다. 여기에서 컴퓨터 시스템이란 컴퓨터를 이루는 구성요소들인 모니터,키보드,메모리, 하드디스크,랜카드를 의미한다. 그렇다고 해서 프로그래머가 모니터, 키보드, 메모리와 같은 기계장치에 직접 명령을 내려야 하는 건 아니다. 인간과 컴퓨터 사이에 운영체제(:12)가 존재하기 때문이다.
  
 Computer System 
   Monitor         | 운 |
   Memory          |    |
   Hard Disk     <-| 영 |--> 프로그래머
   LAN Card      <-|    |-->
   Sound Card      | 체 |
   Printer         |    |
   ....            | 제 |
운영체제가 있는 덕분에 프로그래머는 컴퓨터 기계장치에 직접명령을 내리지 않고, 운영체제를 통해서 간접적으로 명령을 내리는 정도로 컴퓨터 시스템을 제어할 수 있게 된다.

은행창구가 있는 덕분에 복잡한 금융거래를 간단하게 할 수 있는 것과 같은이치다. 돈을 송금하는 과정은 여러단계의 매우 복잡한 과정을 거쳐야 할것이다. 그러나 고객은 그 과정을 알 필요 없다. 그냥 "이돈을 어디어디 계좌로 보내주세요"라는 내용을 적은 명세표만 직원에게 주면 된다. 나머지 일은 창구직원이 알아서 해준다.

시스템 프로그래머에게 있어서 운영체제는 프로그래머와 컴퓨터 시스템간의 창구역할을 하는 프로그램으로 이해하면 될 것이다.

프로그래머가 운영체제에게 어떤 요청을 할때는 이러이러한 일을 해주세요라고 명세표를 작성해야 할 것이다. 이러한 요청을 쉽게 하도록 하기 위해서 운영체제는 시스템 함수라는 것을 제공한다. 예를 들어, 리눅스 운영체제는 메모리할당과 관련되어서 malloc()이라는 시스템 함수를 제공한다. 그러면 프로그래머는 다음과 같은 방법으로 메모리 할당을 요청하게 된다.
malloc(2*1024*1024) /* 2메가의 메모리 공간을 요청 */
요청을 받은 운영체제는 복잡한 과정을 거쳐서 메모리를 할당하고, 메모리가 할당된 공간을 프로그래머에게 알려준다. 이제 프로그래머는 할당된 공간을 이용하기만 하면 된다.

이러한 요청 명세는 안타깝게도 운영체제마다 약간의 차이가 있다. 윈도우와 리눅스가 다르고, 리눅스와 솔라리스가 또 다르다. 때문에 윈도우 시스템 프로그래밍 기술을 리눅스 시스템 프로그래밍을 하는데 이용하는 데에는 많은 어려움이 따른다.


Unix 운영체제 계보
물론 운영체제가 다르다고 해도, 작동방식은 비슷하기 때문에 한쪽 운영체제의 시스템 프로그래밍 지식을 다른 운영체제에서 전혀 써먹을 수 없는 건 아니다. 많은 운영체제들이 운영체제의 할아버지뻘즘 되는 Unix(:12) 운영체제를 그 기반으로 하고 있기 때문에 함수명이라든지 사용방법 기능이 비슷비슷한 경우가 많기 때문이다. 하지만 여전히 어려운건 사실이다.

그러므로 시스템 프로그래밍에 발을 들여놓으려고 한다면, 운영체제를 선택하는게 중요한 요소가 된다. 물론 여기에서는 여러분이 리눅스 운영체제를 선택했다고 가장할 것이다. 왜 리눅스 운영체제를 선택했는지는 아래에서 설명하도록 하겠다.

2.2 리눅스를 선택한 이유 

이론이 있을 수 있지만 모든 운영체제의 아버지는 Unix(:12)이다. 대부분의 운영체제가 Unix(:12)계보를 타고 있다. 맥 OS는 물론이고, Unix 운영체제의 자칭 타칭 경쟁자인 윈도우즈 조차도 Unix의 영향을 받고 있다.

Unix를 아는 것은 운영체제를 아는 것이고 운영체제를 아다는 것은 컴퓨터 시스템을 안다는게 된다.

여기에서 짚고 넘어갈게 있다. 명확히 하자면 Unix는 운영체제가 아니라는 점이다. Unix는 계보라고 보는게 적당하다. 이 Unix 계보안에 Minix, Solaris, Next, Linux, BSD와 같은 운영체제들이 존재한다. 이들 운영체제는 Unix 계보에 포함되기 위한 여러가지 요소들을 충실히 구현하고 있다. 이들을 통들어서 Unix운영체제 혹은 *nix 운영체제라고 한다. Unix 계보에 포함된 다양한 운영체제들은 서로 다른 이름을 가지고 있지만 동일한 계보에 있는 형제들인고로, 사용방법 프로그래밍 방법등이 거의 동일하다. Linux에서 작성된 프로그램은 거의 수정없이 다른 Unix 운영체제에서 동일하게 사용할 수 있다.

왼쪽 유닉스 계보를 보기 바란다. 대략 수십종의 운영체제들이 존재하는걸 알 수 있다. 그런데 왜 하필 리눅스를 선택했을까 ?
  1. 개인적으로 리눅스를 좋아하기 때문이다.
  2. 운영체제 계보의 왕형님격인 Unix를 따르면서도 저렴한데다가 x86 시스템에서 돌아간다. 게다가 Open:::Source(:12)다. Linux에서 배운 프로그래밍 기술은 다른 유닉스 운영체제인 Solaris, BSD 등에도 거의 그대로 적용할 수 있다. 이러한 특징 때문에 한때는 저렴하게 Unix 운영체제를 경험할 수 있는 최고의 학습용 운영체제로 사용되었다. 지금은 최고의 학습용 운영체제일 뿐만 아니라 성공적으로 산업에 진입한 운영체제로 대접을 받고 있다. 산학협력형 운영체제라 할만하다. 

이상 간단하게 리눅스를 선택한 이유를 들어보았다. 학습하기 좋고 산업현장에서도 써먹을 수 있으니 이 아니 좋은가.

ShowComment(323)

2.3 리눅스의 전망 

20세기말까지의 산업구조는 대량생산 대량소비를 달성하기 위한 목적에 부합하게 만들어져 있었다. 이를 위해서 생산시설과 소비시설, 이들을 지원하기 위한 자원과 에너지를 한정된 공간에 집적시키게 된다. 이러한 결과 소비와 생산을 위한 거대도시, 에너지집약적인 산업들 즉 원자력발전소와 대규모 공업단지, 물류단지등이 나타나게 된다.

정보처리산업 역시 마찬가지였다. HP, Oracle, MS, IBM과 메인프레임, Unix에서 볼 수 있는 것처럼 거대하고 강력한 정보처리기계를 만들고, 여기에 자원과 에너지를 집중시켰음을 알 수 있다.

이런 고에너지기반의 산업은 한계에 부닥치게 된다. 에너지가 집적됨에 따라서, 필연적으로 발생하는 환경오염, 거대하고 기계화된 조직을 관리하기 위한 방만하고 비효율적인 관리조직, 자원의 급격한 고갈이라는 문제때문에 발생하는 비용이 에너지를 집적함으로써 얻을 수 있는 이익을 초과하는 시점에 다다랐기 때문이다.

이렇게 되어서, 거대한 도시를 유지하는 대신에 소규모의 여러개의 도시를 유지하고 이들을 네트워크로 묶고 권한을 분산하는 정책을 사용하게 된다. 이렇게 되자, 산업구조역시 바뀌게 되는데, 대규모화된 도시의 획일화된 소비패턴을 지원하기 위한 획일화된 대규모 공업단지를 유지하는 대신에, 각 지역에 분산된 공간에서 각 소비자의 특징에 맞는 물건을 생산하는 방식의 구조적인 변화가 진행이 된다.

이렇게 산업과 도시생활패턴이 변경되자. 정보처리 산업역시 그러한 방식으로 변화가 된다. Web2.0, 개인화, SN, 블로그, SA등 분산과 네트워크 효과를 중요시 하게 되고, 이에 따라서, 거대하고 강력한 정보처리기계, 소프트웨어를 사용하는 대신에, 유연하고 자유롭게 제어가능한 하드웨어와 소프트웨어의 사용을 지향하게 된다. 덜 강력하고 덜 비싼 자원을 사용하는 대신에, 각각의 자원에 권한을 분산시키고, 이를 네트워크화 해서 원하는 정보를 얻어내는 그런 환경이다.

리눅스와 Mysql, Apache 기타 수많은 공개소프트웨어들이 - 충분히 성숙하지 못했음에도 불구하고 - 각광을 받는 것은 우연이 아니라 필연이다.

리눅스는 이러한 산업과 생활패턴의 변화에 따라서, 그 영역을 지속적으로 확대해 나갈 것이다.



출처 - http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/system_programing/Book_LSP/Ch01_Intro



'Development > Linux Programming' 카테고리의 다른 글

linux prog - linux startup  (0) 2013.10.03
linux programming - library  (0) 2013.10.03
Posted by linuxism
,