원자폭탄, 기타 이것저것

20세기에 인간이 이뤄낸 위대한 과학 성과 중 하나는 원자력에 대한 지식이다.
학생들이 무려 고등학교나 대학 학부 수준에서 배우는 물리 교재에 chapter가 하나 추가될 정도로, 종전의 고전 역학과는 차원이 다른 지식이 추가되었다.
 
이를 바탕으로 인간은 예전에는 미처 상상도 할 수 없던 어마어마한 동력과 에너지를 얻을 수 있게 되었다.
원자력 발전은 태양에 전혀 근간을 두지 않고 에너지를 얻는 거의 유일한 방법이기도 하다.
20세기 이후에 시작된 찬란한 전기 문명은, 교류 전기의 실용화와 더불어 원자력 발전도 큰 일조를 했음을 부인할 수 없을 것이다.
 
그러나 원자력은 이내 핵무기라는 것을 만들었고, 국제 사회 정세를 완전히 다른 양상으로 바꿔 놓기도 했다. 예전에는 마음에 안 들면 애들처럼 서로 주먹으로나 툭탁거리고 싸우던 것이, 이제는 총을 손에 쥔 거나 마찬가지가 됐다는 소리이다.
 
현재까지 인류 역사상 자국민이 사는 도시에 핵무기를 맞아 본 나라는, 잘 알다시피 전세계에서 일본이 유일하다. 그것도 두 번이나 맞았다. 2차 세계대전의 말기에 유럽에 독일, 이탈리아는 다 항복하고 히틀러마저 제거됐는데 아직 일본만 유일하게 개기고 있어서 저랬다. '무시무시한 폭탄'을 맞고서야 정신을 차린 일본은 왕이 직접 서면으로 연합국에 항복하고, 자기 식민지들에 대한 권리도 일체 포기한다. 그래서 2차 세계대전이 정말 극적으로 끝나고, 우리나라도 일제로부터 해방된다.

아마 우리나라가 이렇게 당했으면 미국하고는 완전 철천지원수가 됐을 것이다. 방사선 피폭은 대물림까지 된다. 그 데미지의 레벨이 6 25 때 무슨 노근리 학살 같은 거하고 비교가 되나?
 
잘 알다시피 원폭은 1945년 8월 6일에 히로시마 상공에 먼저 떨어졌다. 의역 좀 하면 '귀여운 꼬마애'뻘 되는 길이 약 3미터, 무게 약 4톤쯤 되는 Little Boy 폭탄이 어지간한 여객기 고도와 비슷한 9.5km 상공에서 전투기로부터 투하되었다. 타이머를 걸었는지 뭐 어떻게 activate가 됐는지는 모르겠지만, 그 폭탄은 한참을 추락하다가 약 550m 상공에서 그대로 펑 터졌다.
수류탄도 그렇고 폭발물은 약간 공중에서 터져야 사방팔방으로 가장 큰 파괴력이 나오는 법. 이 원폭도 일종의 공중 폭발을 일으켰다.
 
곧바로 눈을 보호하기 위해 가글을 착용한 당시의 전투기 승무원들은 정말 경악할 만한 광경을 목격하게 됐을 것이다.
이것은 보어, 페르미, 천재 컴퓨터 과학자인 폰 노이만 등 이름만 들어도 아는 당대의 저명한 과학자들이 일본 본토 지형을 치밀하게 분석하고, 폭탄을 어디에서 투하하고 터뜨려야 가장 큰 피해가 나오는지까지 계산하여 진행한 프로젝트였다. 그 첫 실험 대상으로 일본이 선택된 것이다.
 
눈을 상하게 할 정도의 엄청난 섬광이 비쳤다가, 정신을 차리고 보니 어마어마한 불기둥과 무시무시한 후폭풍. 하늘이 어두워지고 그저 도미노처럼 힘없이 주저앉는 건물들. 영화보다 더 영화 같은 순간.
아마 핵실험 촬영 같은 것도 수십 킬로미터 떨어진 곳에서 zoom 무지막지하게 당겨서, 과장 좀 보태면 천체 활동 관측하듯이 해야 하지 않을까 싶다.

히로시마 시는 순식간에 폐허가 되었다. 죽은 사람 시체 사진을 보니까 거의 유대인 홀로코스트 내지 관동 대지진 학살 사진 수준이었다.
물론 그 며칠 전에 미국에서는 원폭 투하를 예고하고 어서 대피하라는 경고 전단지를 살포하긴 했었다고 한다.
하지만 대부분의 사람들은 사고방식이 "설마? 뭐 좀 위력이 큰 폭탄 떨어져 봤자, 늘 하던 대로 방공호로 대피하면 되겠지" 수준이었으며, 결국 원폭에 고스란히 당했다고 전해진다.
 
  (이런 예화는 기독교에서 복음 전할 때 자주 인용, 등장하기도 한다.)
 
나는 일본에 대해 완전 몸서리치게 증오하거나 딱히 피해 의식이 있지는 않다. 원폭 맞아서 도시 전체가 저렇게 개떡이 되고 만 것은, "꼬시다 쌤통이다 메롱"까지는 아니더라도, 감정 배제하고 객관적으로 봐도 정말 일본이 자기네가 심은 대로 거둔 것이다.
 
우리한테 한 짓이 얼마인데! 특히 잊어서는 안 되는 그들의 죄악 중 하나는, 관동 대지진 때 민심이 흉흉해지니까 조선인들을 폭도로 몰아서 수천, 수만 명을 다 학살하고, 그걸 일본 경찰과 정부 당국은 일부러 묵인까지 해 준 사실이다. 독립 운동 항일 투쟁을 하던 사람도 아니고 멀쩡한 민간인을! 사태가 수습된 뒤에도 이 학살극에 대해 법적으로 책임을 진 쪽은 일본에 아무도 없었다.
 
외모가 비슷하니까 일부러 한국인이 발음하기 힘든 일본어 단어를 발음까지 시켜서 사람을 죽였으며, 그러다 심지어 몇몇 자국인도 오인 살해 당했다고 한다. 성경에서 사사기 12장 5~6절을 읽어볼 것. 오히려 조선인을 단원으로 고용하고 있는 야쿠자 같은 조직에서 조직원의 목숨이 위태로우니 애써 숨겨 줬을 정도라고 한다. 그러니 저런 죄값쯤은 좀 치러야 하지 않겠는가? (물론 원폭 피해자 중에서도 조선인이 일부 있었지만.)
 
그럼에도 불구하고 일본은 자기가 저지른 죄에 대한 언급이나 진정한 반성과 사죄는 싹 회피하고, 오로지 핵폭탄을 맞아 자기네가 불쌍한 피해자인 것만 부각시키면서 동정을 호소하고 있으니, 경계해야 할 점이 아닐 수 없다. "다시는 이런 실수 되풀이하지 않겠습니다"... 일본 문화 특유의 뱅뱅 돌려 말하는 모호한 표현인데.. 도대체 그들은 무엇을 실수라고 생각하는 걸까?
 
'귀여운 꼬마애'를 실은 전투기를 조종한 사람은 폴 티베츠라는 베테랑 공군 조종사이다. 당시 30대 초반의 혈기왕성한 대령이던 그는 2차 세계대전을 종식시키는 데 일조한 영웅으로 미국 내에서 추앙 받았으며, 나중에 원스타 준장으로까지 진급한 후 전역했다. 그리고 천수를 누리며 굉장히 오래 살다 2007년에 작고했다.
그는 2002년이던가 미디어를 통해, 당시의 원폭 투하는 그저 명령에만 따른 것일 뿐 딱히 개인의 양심의 가책을 느끼지는 않는다고 회고했다.
 
사흘 뒤 나가사키 상공에 투하된 원폭은 원판보다 더 뚱뚱하고 위력도 좀더 강해진 것이었다. 하지만 평지인 히로시마와는 달리 나가사키는 지형의 기복이 큰 편이어서 히로시마 만한 데미지는 나지 않았다.
 
핵무기까지 가미된 2차 세계대전을 겪은 후 세계 지성인들의 세계관, 인간관은 정말 큰 변화를 겪게 되었음이 틀림없다. 아마 성선설에 대한 믿음이 크게 흔들리게 됐을 것이고, 이런 과학 기술로 이런 규모의 전쟁이 앞으로 더 터졌다간 진짜 지구가 멸망할 거라는 경각심을 갖게 됐을 것이다. 그러니 국가 위의 다른 중재 조직이라도 만들어서 세계 열강이 또다시 이런 끔찍한 전쟁에 도미노처럼 휘말리는 것만은 무슨 수를 써서라도 막아야 한다는 생각을 했을 것이다.
 
그래서 유명무실하던 국제 연맹도 없애고 국제 연합이라는 조직이 새로 생겼다. 그러나 그런다고 해서 세상에 전쟁이 없어지지는 않고 있다. 사악한 자에겐 결코 평화가 없다고 말하는 주님의 이사야서 말씀을 기억하자.
 
어쩌면 6 25 전쟁이 장기화되었다면, 냉전이고 나발이고 없이 2차 세계 대전이 끝난 지 10년이 채 안 지나서 한반도에서 거의 세계 대전급의 피터지는 싸움이 또 벌어졌을지도 모르며, 최악의 경우 핵무기가 또 동원되게 됐을지도 모르겠다. 특히 우리나라에서는 맥아더 장군을 욕하고 비판하는 진영이 이런 점을 주로 들추곤 한다. 하지만 이런 진영은 그 불행의 근본 원인 제공자에 대해서는 이상하리만치 언급이 없고, 저런 식의 주장을 하는 의도가 매우 불순한지라 본인은 별다른 의미를 두지 않는다. (아무리 생각해도 정말 불순하다.)
 
사실 6 25도 1951년 하반기 이후부터는 38선 인근에서의 지겨운 엎치락뒷치락 소모전 위주였기 때문에, 미국도 필요 이상으로 소련 심기를 건드리고 싶지도 않았으며 어지간해서는 승산 없는 이 전쟁에서 적당히 손 떼고 싶었을 것이다. 이승만, 맥아더 같은 짝짜꿍이 맞는 꼴통(?)들만이 오로지 북진 통일을 고집했던 것이다.
 
그 후 세월이 흘러 박정희 정권은 70년대 말에 우리나라도 전투기와 핵무기를 제외한 모든 무기를 국산화했다고 선언했다. 이는 박 대통령의 적극적인 지원 하에 국방 과학 연구소 연구원들이 헌신적으로 노력한 덕분이었다.
 
그는 더 나아가, 우리가 북한과 일본, 미국을 상대로 당당히 큰소리 치려면 우리도 핵무기를 만들어 내야 한다고 생각했다. 박정희가 부하의 총에 맞아 비명에 가지 않았다면, 그리고 이휘소 박사 같은 사람이 그렇게 허무하게 가지 않았다면 한국의 역사가 또 바뀔 수 있었을까? 얘기를 더 하자면 정치성 논쟁이 되므로 이 자리에서는 생략하겠다. (그런데 정작 이휘소 당사자는 오히려 유신 독재와 핵무기 개발을 강력 반대했던 걸로 유명하다. 김진명 씨의 소설에 나오는 설정은 허구이다 ^^)
 
아무쪼록 이 바닥으로 글을 쓰면서 또 느낀 것은, 역시 아는 것이 힘이고 냉혹한 세상에서는 힘이 최고라는 것. 어차피 강자와 약자가 둘 다 시편 20:7 말씀을 모르거나 안 믿는 상황이라면 말이다.
"무기를 만드는 자는 지배자가 되고 방패를 만들지 않는 자는 노예가 된다는 진리"는 돌도끼로 전쟁을 할 때부터 미사일로 전쟁을 할 때까지 인류문명이 만들어 놓은 진리이다. 과거에 우리나라가 힘이 없어서 일제에 주권을 빼앗기지 않았던가.
 
우리나라 국민들이, 일본에 대한 증오심과 적개심이 부족해서 양국의 국력 차이가 그 정도이고 우리가 이렇게 살고 있는 게 절대 아니다. 일본에 있는 동급의 저질 찌질이들하고 같이 댓글 논쟁, 사이트 DDOS 공격이나 주고받으면서 그게 애국인 줄로 착각하지는 말아야 한다.
일본으로부터 받아낼 건 비용 대 효율 최대로 받아내고, 말 없이, 모방을 통해 창조를 해 내고, 실력을 쌓고 기술을 개발하고 국부를 창출하는 것이 일본을 가장 수준 높게 이기는 것이다. 일본을 그런 방법으로 이기려고 애썼던 옛날 지도자의 공도 과와 더불어 객관적으로 인정과 평가를 받아야 하지 않나 싶다.
 
덧.
이 글의 전반적인 논조로부터 느껴졌겠지만, 본인은 원자력 발전 찬성이고, 핵무기 개발도 그렇게 반대 안 한다. 남이 만들면 우리도 해야 된다 주의에 가깝다. -_-;; 그깟 인본주의적인 반핵 반전 운동 한다고 해서 세계 평화가 유지될 거라고 믿지 않는다.

Posted by 사무엘

2010/01/11 10:01 2010/01/11 10:01
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/81

코트 안의 마물

제가 초등학생이던 시절, 미국 역사에 대해 쓰인 책을 읽고 있었는데 "보스턴 차 사건"이라는 걸 접했습니다.
그때 저는 미국의 독립 운동가들이 야적장에 쌓여 있던 영국산 자동차들에다 불을 질렀거나 무역선에 실려 있던 자동차를 다 바다에 처박아 넣은 걸로 생각했습니다.
그 당시는 자동차가 발명된 시기하고 미국이 건국된 시기를 연계해서 보는 안목이 없었을 뿐더러 어휘력이 부족했기 때문이지요. =_=;;

마치 "코트의 안에는 마물이 살고 있어"를 듣고는 사람이 입는 코트 안에 괴물이 숨어있는 장면을 떠올리는 것과 같은 맥락입니다. -_-;; (coat가 아니라 court입니다. In the court lives a demon ㅋㅋㅋ)

하지만 그 차가 자동차가 아니라 마시는 차의 원료라는 것은,
그래도 스페인과 에스파냐가 동일한 나라인 걸 깨달은 것보다는 일찍 깨달았습니다.
저는 고등학교 때까지만 해도 무적 함대(영국에게 격파 당한)를 갖췄던 천주교 국가 스페인은 유럽에 있고,
투우로 유명한 에스파냐는 멕시코 같은 라틴 아메리카 중남미에 있는 나라인 줄 알고 있었습니다. -_-;;

특히 외래어를 표기할 때, 귀차니즘에 입각하여 장음을 따로 반영하지 않게 됨으로써, 외래어의 동음이의어 모호성도 꽤 심각한 수준이 되지 않았나 생각됩니다.
한자어 동음이의어랑 똑같죠. 더구나 한자와는 달리 영어 알파벳은 컴퓨터로 치기도 아주 수월하니 영단어 혼용은 앞으로 더욱 심해질 것 같습니다.

리드: lead (지도/통솔), read (읽기), reed (갈대, 악기 부품), lid (뚜껑)
코드: code (부호, 정보, 성향), chord (음악 용어 화음), cord (전기 플러그가 연결된 줄)

결론: 코트 안의 마물은 마치 귓속에 도청 장치만큼이나 임팩트가 큽니다. ㅋㅋ

Posted by 사무엘

2010/01/11 10:00 2010/01/11 10:00
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/80

레거시 코드

꽤 희귀한 기회 덕분에,
한때 시대를 풍미했던 상업용 소프트웨어의 소스를 구경하게 됐습니다.

윈도우 3.1에서 돌아가는 녀석이었거든요.
저야 도스박스에다 윈도우 3.1 + 비주얼 C++ 1.5도 갖추고 있어서 이걸로 돌려도 되지만
32비트로 포팅을 해 보고 싶어서 최신 개발툴로 프로젝트를 만들고 빌드를 해 봤습니다.
당연히 바로 빌드는 안 되고 수백여 군데에서 에러가 나는데...
16비트 윈도우 코드의 특징을 한눈에 알 수 있었습니다.

1. precompiled header가 없었는지 매 소스 파일마다 <windows.h> 인클루드.

2. 말로만 듣던 far, huge 포인터의 압박. 메모리 모델별로 malloc이라든가 포인터를 다루는 함수도 따로 존재. _fmalloc 같은.

3. POINT 구조체. 옛날엔 POINT 구조체의 x,y 멤버가 16비트 크기였기 때문에 32비트 long 하나로 POINT를 나타내는 게 관행이었으며, 심지어 lParam *을 POINT *로 바로 캐스트하는 MAKEPOINT 같은 매크로까지 존재했습니다. 하지만 지금은 좌표계가 32비트로 커지고 이것 때문에 MoveTo, SetWindowOrg, SetViewportExt 같은 함수들은 모두 Ex가 붙은 형태로 프로토타입이 바뀌게 됐죠.

4. 옛날에는 핸들(HANDLE, HINSTANCE, HGDIOBJ, HWND 등등)은 전부 void *의 typedef였고, 아무 형변환 없이 마음대로 섞어 썼습니다. 이 폐해를 막으려고 지금은 STRICT(엄격한 타입 구분)라는 개념이 추가됐지만 어마어마한 분량의 레거시 코드를 컴파일시키려면 그 옵션을 꺼야 하죠.

5. WM_CTLCOLOR 메시지. 옛날에는 이 메시지 하나만 왔지만 지금은 WM_CTLCOLORBTN, DLG, EDIT, LISTBOX 등으로 세분화됐습니다. 다만, 16비트 관행을 물려받은 MFC는 여전히 OnCtlColor 라는 한 함수로 이 메시지들을 모두 처리합니다.

6. 멀건 윈도우 3.1 대화상자에다가 은빛 3차원 효과를 입혀 주는 ctl3d.dll과 교신을 하는 흔적. 그러고 보니 그때는 이런 효과가 지금의 공용 컨트롤 6.0 매니페스트 같은 그런 매개체였던 것 같습니다. MFC에도 CWinApp 클래스에 Enable3dControls 같은 멤버 함수가 있을 정도였는데, 이제는 완전히 deprecated로 처리되죠.

7. DLL도 아니고 EXE에 웬 export 속성이 지정된 함수? 그것도 __declspec(dllexport) 같은 지금 통용되는 문법으로 작성된 것도 아닙니다.
16비트 윈도우 EXE는 헥사 에디터로 들여다보면, 윈도우/대화상자 프로시저처럼 운영체제로부터 호출을 받는 콜백 함수들의 이름을 따로 name table에다 등재를 해 놓는 경우가 많더군요. 꼭 그렇게 할 필요는 없는데 왜 그러는지 궁금.. 디버깅 정보와 관련이 있는지, 아니면 속도를 높이려고 그러는지 이유는 모르겠습니다.

8. C++ 문법이 바뀌어서 옛날에는 허용되었으나 지금은 허용되지 않는 몇몇 문법들

맥이나 리눅스 같은 다른 플랫폼들은 도스 같은 극악의 호환성 발목은 없었겠지만, 16비트를 겪은 시절조차 전혀 없었는지가 문득 궁금해지네요.

참고로 저는 C/C++은 32비트 도스 익스텐더 환경에서(왓콤, DJGPP) 처음 시작했고 16비트는 거의 접한 적이 없는 세대입니다. ^^

Posted by 사무엘

2010/01/11 09:58 2010/01/11 09:58
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/79

비행기의 추억

1. 공항 가는 길: 드넓은 공항 고속도로와 늘 텅 비어 다니는 공항 철도. 주변 갯벌과 영종 대교의 경치가 무척 인상적이다. 서울에 살면서 짐이 별로 없이 혼자 비행기 탈 때야 싸고 쾌적한 공항 철도가 짱이지만, 공항 철도 수혜권의 밖에 있는 사람이 훨씬 더 많은 게 문제.

2. 으리으리한 인천 공항 여객 터미널: 리무진으로 공항에 갔다면 3층인 출발층에 코앞에서 내리겠지만, 자가용을 갖고 갔다면 지하 주차장, 그리고 철도를 이용했다면 역시 지하에서 내리므로 터미널까지 한참을 걷고 올라가야 한다.
돈 뽑기, 환전이나 휴대전화 로밍 같은 시설은 널렸으니 전혀 걱정할 필요 없다. 전세계에서 통용되는 만능 콘센트 같은 것도 면세점에 가면 다 있다. 하지만 환전은 인터넷으로 미리 해 가야 싸다. 시계 같은 건 군부대 앞에 있는 사제품을 사는 것보다야 미리 챙겨 가는 게 더 나은 것과 같은 이치.

3. 출국 수속: 맨 윗층(3층)인 출국층으로 올라가, 내가 타는 비행기가 소속되어 있는 항공사의 부스로 간다. 짐이 많으면 카트 하나 끌고 긴 줄을 따라 기다린 후, 자기 차례가 되면 출국 수속을 받는다. 미리 프린트해 놓은 E티켓과 여권을 제시하면 되는데, 항공사에 따라서는 아예 E티켓은 보지도 않고 여권만 주면 되는 경우도 있더라.

이 시점에서 항공권이 발권된다. 직원이 어디 앉고 싶냐고 보통 묻는다. 나는 늘 창가 쪽 좌석을 달라고 했고 그럼 그렇게 티켓이 나왔다. 신체 건강한 성인이라면 비상구 쪽 좌석을 달라고 해도 된다. 발을 길게 뻗을 수 있어 무척 편한 자리인 반면, 여기 앉은 승객은 사고가 났을 때 승무원과 같이 다른 승객들 구조를 도와야 할 의무가 있다. 이건 항공업계에 법으로 규정된 사항이며, 이 때문에 비상구 좌석은 그렇게 할 능력이 있고 그 의무에 동의하는 승객에게만 발권된다.

4. 소지품: 고속버스의 내부에 짐칸과 객실 내 선반이 따로 있듯이, 비행기를 탈 때도 승객은 큰 짐은 따로 부칠 수 있으며, 작은 짐은 그냥 기내에 갖고 들어갈 수 있다. 부치는 짐은 출국 수속을 할 때 무게를 재고 간단히 보안 검사를 한 후, 항공사 측으로 인계하게 된다. 옷가지나 세면도구, 책처럼 당장은 없어도 되면서 싸고 부피가 비교적 크고, 잃어버려도 그렇게 큰 손해가 아닌 짐은 응당 부치면 된다.

부치는 짐은 수송하는 과정에서 컨베이어 벨트 위에 쿵쿵 떨어지기도 하고 직원들이 막 던지기도 한다. 수송 과정을 직접 눈으로 보면 정말 '식겁'을 할 거라던데.. 그러므로 충격에 약한 물품은 부칠 때 각별히 주의해야 한다. 또한 승객들끼리 짐이 뒤바뀌는 불상사를 막기 위해 가방 손잡이 같은 데에다 나만 식별할 수 있는 색깔의 손수건을 묶거나 표식을 미리 해 두는 게 좋다. 무게도 미리 재어서 테스트해 보는 것 역시 상식.

비행기에는 기내에 휴대 반입이 가능한 짐이 있고, 기내 반입이 안 되어 부쳐야만 하는 짐이 있으며, 아예 부치지도 못하는 짐도 있다. 참고로 기내에는 손톱깎이나 커터 같은 작은 쇠붙이도 갖고 들어갈 수 없으며 이런 건 부쳐야 한다. 비행기에 실을 수 없는 물품에 대해서는 소지를 그냥 포기하고 불우이웃 시설에 기증(?)하라는 물품 포기함도 공항 내부에 있다. ^^;;
이런 것과는 반대로 디지털 카메라, 노트북 같은 고가의 전자 기기들은 부치지 말고 기내에서 개인이 직접 휴대해야 한다.

5. paid 구역으로: 이제 탑승권을 받았으므로 paid 구역으로 들어간다. 돌아올 수 없는 강을 건너는 것이다. 철도처럼 자동 개집표기 같은 건 없고, 입구를 지키고 있는 직원에게 여권과 탑승권을 제시하면 바로 들어갈 수 있다. 곧바로 우리를 기다리고 있는 건 보안 검색대이다. 가방, 주머니 속의 소지품, 웃옷 다 꺼내서 바구니에 얹고, 본인도 신발 벗고 검색대를 통과하면 된다.

6. 출국 심사: 검색대를 통과한 후 출국 심사를 받는다. 출국 금지된 블랙리스트 등재 인물이 아닌지만 파악하는 과정이므로 우리 같은 사람에게는 해당 사항 없다. -_-
여권과 비행기 탑승권을 제시하면 직원이 여권에다가 우리 공항을 이용하여 출국했다는 도장을 찍어 준다.

7. 대기: 출국 심사까지 마쳤으니 남은 것은, 면세점 쇼핑을 즐기다가 내가 타는 탑승구를 찾아가 비행기에 타는 것뿐이다. 타는곳이 확장 탑승동에 있다면 아직 갈 길이 한참 머니 지하로 가서 셔틀 전철을 타야 한다. 이 구역 내부는 무선 인터넷도 무료로 잘 돌아가고 있으니, 노트북을 갖고 있고 아직 시간이 많이 남았으면 인터넷을 즐겨도 좋다. 비행기 안에서는 인터넷이 안 되므로 어차피 배터리 다 쓸 거면 지금 쓰는 게 낫다.

8. 탑승: 각 게이트별로 아담한 대기실(?)이 있고 승객들이 앉아서 게이트가 열리기를 기다리고 있을 것이다. 그러다 게이트가 열리면 비행기로 탑승이 시작되는데, 보통 1등석 승객과 노약자 장애인부터 가장 먼저 들어가고 일반실 승객도 좌석 번호에 따른 구역별로 승무원의 통제에 따라 탑승하게 된다. 1등석 승객과 다른 승객들은 들어가는 길이 분리되어 있기 때문에 일반실 승객은 2등석까지는 잠시 구경할 수 있어도 1등석을 구경할 일은 잘 없다.
좁은 통로를 지나서 드디어 비행기 내부에 들어간다. 일반실은 좌석이 굉장히 작아서 KTX 일반실 내지 일반과 비슷하다. 버스처럼 안전 벨트가 있고, 다른 교통수단에는 없던 담요가 있다. 그리고 식수가 비치되어 있다.

9. 출발: 비행기를 타는 건 굉장히 큰 일이다. 보통 승객들도 예상 시각보다 훨씬 더 일찍 맞춰서 공항에 알아서 오고 대비를 한다. 작은 공항의 경우 타기로 예정된 승객들만 다 타면 예정 시각보다 먼저 비행기가 출발해 버리는 경우도 있는 있다. 하지만 비행기가 엄청 많이 드나들고 활주로를 조직적으로 사용해야 하는 인천 같은 큰 공항은 그러지는 못할 것이다.

비행기가 활주로까지 이동하는 것은 꼭 버스가 출발하는 것과 별 차이 없는 느낌이다. 이 동안 우리 항공사를 이용해 줘서 고맙다는 안내 방송과 함께 비상시 대처 요령 같은 게 비디오로 흘러나올 것이다. 그리고 곧 이륙을 할 것이므로 안전 벨트 채우고 전자 기기를 다 꺼 달라는 당부가 나온다. 비행기 내부에서는 이착륙 중엔 안전을 위해 일체의 전자 기기 사용이 금지되며, 순항 중일 때에나 통신 기능이 없는 기기만 사용할 수 있다. 따라서 기내에서 비행기의 이착륙 중에 창밖 풍경을 찍은 동영상은(유튜브에도 있다) 마치 예비군 훈련장 내부 사진(역시 블로그에 나돈다)만큼이나 규정을 어기고 몰래 찍은 것이다.

10. 이륙: 이륙이 시작되면 비행기의 엔진 소리 옥타브가 급증하고 바람 가르는 소리가 거칠게 나기 시작한다. 짜릿하다. 비행기는 정말 이 맛에 탄다. 그리고 갑자기 지구의 중력 가속도의 값이 바뀐 듯한 느낌과 함께 비행기는 공중으로 뜨고 경사감이 느껴진다. 바깥 건물과 도로들이 장난감처럼 작아져 보이기 시작하며 구름마저도 아래로 보이게 된다.

본인의 경험상 인천 공항에서 갓 출발한 비행기가 이륙하기까지 걸리는 시간은 거의 15~20분 정도로 일정했다. 택싱 내지 대기 시간이 그만치 걸린다는 뜻이다.

11. 순항: 이제 비행기 안에서 즐거운 시간을 보내는 일만 남았다. 거리에 따라서 기내식이 한두 번 나올 것이고, 일부 노선의 경우 면세품을 파는 카트도 돌 것이다. 기내식은 식사도 있고 음료수+과자 간식도 있다.
아 그리고, 입국 신고서도 여행 중에 배부된다. 당신이 불법 체류자가 아닌 정당한 여행객인지(님의 신분은? 입국 후 어디 체류할 예정?), 생물학적으로 위험한 물품을 반입하고 있는지, 세관에 신고해야 할 귀중품이 있는지 등을 아주 형식적으로 조사하는 것이다. 대부분 해당 사항이 없는 질문들에 답변하여 입국 심사 때 제출하면 된다.

비행기에도 승객이 바깥 경치 좀 구경하라고 창문이 있다. 하지만 비행기 창문은 모든 교통수단들 중 가장 작으며 그 이유는 더 설명할 필요가 없을 것이다. 이착륙 중일 때는 승무원들이 돌아다니면서 창문을 다 열어 달라고 하며, 반대로 긴 시간 순항 모드일 때는 자는 승객도 있고 하니 창문을 닫아 놓고 기내를 전반적으로 깜깜하게 해 놓는다. 따라서 객실 조명에 관한 한 비행기는 고속버스와 비슷한 셈이다.
(당연한 말이지만 비행기 창문을 연다는 말은 블라인드로 가려졌던 유리창을 보이게 한다는 뜻하는 말이지, 바깥 공기와 객실 공기 사이를 개방한다는 뜻은 절대 아님. ㅋㅋㅋ)

지금 모든 대중교통들이 그렇듯이 비행기 내부에서도 흡연은 엄격히 금지이다. 특히 화장실 안에서 몰래 피우는 건 금기 1순위이다. 담배 연기가 화재로 오인이라도 됐다간 망신 톡톡히 당한다. 아예 담배 자체를 기내 반입 금지 물품으로 분류하는 건 아닌가 모르겠다. 라이터는 말할 것도 없고!
몇십 년 전만 해도 간접 흡연 때문에 폐암 걸린 스튜어디스가 소송 제기까지 했었는데 세상 참 많이 변했다.

※ 글을 맺으며

비행기 몇 번 타 보지도 않았는데 그래도 생생한 기억이 남아 있어서 몇 자 정리해 보았다. 착륙 쪽은 쓰자니 너무 힘들어서.. 여기까지만. -_-

그 집채만한 배가 바다에 어떻게 떠 다니는지는 솔직히 이해가 된다. 배만 중력이 있는 게 아니라 유체에도 중력이 있으며, 근본적으로 물도 그렇게 호락호락 가벼운 물질이지는 않기 때문이다. 하지만, 그 집채만한 비행기가 어떻게 하늘로 뜰 수 있는지는 나는 아직까진 도저히 이해를 못 하겠다. 그냥 무슨무슨 법칙과 수학 공식으로 설명을 하더라도 내 마음으로 "실감"이 가지는 않는다. 더구나 그냥 뜨는 것도 모자라 전투기 에어쇼 같은 건 도대체 어떻게 하는지??

오늘날의 고정익 비행기는 정말 잘 통제된 아슬아슬한 조건 하에서만 뜰 수 있다. 새처럼 자기만 혼자 곱게 뜨는 게 아니라 주변에 온갖 side effect를 남기기 때문에 정말 깔끔하게 잘 정돈된 활주로도 필요하며 주변에 아무것도 없어야 한다.

조류 충돌 같은 건 상상도 하기 싫은 악몽이다. 엔진이 풀로 돌아가고 있는 팬으로 불순물이 빨려 들어갔다간 작살 난다. 그래서 화산이 폭발해도 화산재와 먼지가 무서우니 그쪽은 피해서 비행해야 하고, 심지어 비행기 위에 쌓인 눈도 깨끗이 청소해야 한다. 눈 때문에 무거워서가 아니라, 눈이 쌓임으로써 비행기 날개의 표면 외형을 왜곡하여 날개가 만들어내는 양력 효율을 크게 떨어뜨리기 때문이다.

비행기 활주로는 무거운 비행기의 착륙 충격을 견딜 수 있게 일반 도로보다 훨씬 더 튼튼하고 특수하게 건설된다. 비행기 타이어도 자동차 타이어보다 훨씬 더 비싸고 고급 재질로 만들어지며 교환 주기가 짧다. 타이어 내부에는 화재의 요인을 원천 봉쇄하기 위해, 산소가 전혀 없이 비활성 기체인 질소만으로 100% 주입한다. 물론 지구 대기도 이미 80%가 질소이긴 하지만.
비행기 타이어가 터지면 터진 부분만 땜질한다는 건 있을 수 없는 일이며, 전체를 교체해야 한다. 한번 착륙을 수행한 비행기는 타이어가 굉장히 열과 무리를 많이 받아 있기 때문에, 몇 시간씩 식히고 쉬게 해 줘야 한다.

V1 속도를 넘어서면 이륙을 중단할 수 없이 무조건 떠야 하며, 연료 소비를 감안하여 이륙할 때와 착륙할 때의 허용 무게도 다 정해져 있다. 그래서 이륙했다가 곧장 다시 착륙하면 아직 연료 때문에 비행기가 많이 무거운 상태인지라 활주로와 비행기에 심한 무리를 줄 수 있다.
이런 이유로 인해 비행기는 긴급 환자 발생 같은 비상 사태로 인해 목적지에 도달하지 못하고 조기 착륙할 경우, 선회 비행을 하면서 아깝지만 연료를 버려야 한다. 어떻게든 정상 운항 후 착륙할 때와 같은 무게를 맞춰야 하기 때문에.

정말 복잡하지 않은가?
이래서 사람이 만든 날개는 역시 신이 만든 날개보다는 불완전한 건지도 모르겠다.
사냥꾼의 총에 맞아 추락한 새가 땅에 떨어지면서 폭발과 화재를 일으키지는 않는다는 게 대단하다. =_=;;

사용자 삽입 이미지
사용자 삽입 이미지

Posted by 사무엘

2010/01/11 09:57 2010/01/11 09:57
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/78

가는달, 굵은달, 버금달, 둥근모, 뻗음, 짧은둥근모, 짧은뻗음 (도깨비):
  모두 90년대 김 중태 님의 작품이다. 도스용 PC 통신 프로그램 이야기에도 이런 계보의 글꼴을 다수 볼 수 있었다.
특히 둥근모와 뻗음 류의 글꼴은 개인적으로도 무척 좋아하며, 심지어 전철 전광판에서도 볼 수 있다.

바탕, 가는돋움, 가는샘물, 필기 (custom):
  도스용 아래아한글 1.x가 제공하던 화면용 글꼴의 명조, 고딕, 샘물, 필기에 각각 해당한다. 고정된 도깨비 식 조합 테이블이 아니라 <날개셋> 5.3에서 첫 도입된 custom 조합 테이블을 사용했으며, 바탕과 샘물은 아래아한글 1.x 수준의 간단한 옛한글도 표현할 수 있다.
글꼴에 맞게 튜닝된 조합 테이블을 내장하고 있을 뿐더러 상업용 프로그램에서 사용되기도 한 만큼 글꼴의 품질은 무척 좋은 편이다. 다만, 다음에 나올 5.31에서 가는돋움은 아래아한글의 그 고딕체과 유사한 느낌이면서 더 깔끔하고 보기 좋은 다른 글꼴로 대체될 예정이다.

이야기체 (도깨비):
  한메 타자교사와 이야기 5.3이 사용하여 아주 널리 알려진 그 글꼴이다. 식상한 명조 고딕 류에서 탈피했고 나름 가독성도 좋아서 무척 잘 만든 글꼴이란 생각이 든다.

한솔바탕 (도깨비):
  도스용 수채화 2.x에서 유일하게 본 걸로 기억한다. 이것도 꽤 참신한 디자인이고 그럭저럭 쓸 만하다.

파도, 가는파도, 흘린둥근고딕 (도깨비):
  이 글꼴들은 화면용 16*16뿐만 아니라 출력용 자형도 있어서 아래아한글 HFT로도 변환되어 쓰였던 것 같다.

마소바탕 (custom):
  과거 MSHBIOS가 내부적으로 사용하던 글꼴을 완벽하게 재현한 것으로, 윈도우 3.1의 완성형 바탕체 글꼴의 짝퉁이라 할 수 있다. 조합 규칙이 도깨비와 살짝 다른 면이 있다. 미려한 것 같으면서도 철저하게 테스트를 안 하고 대충 어설프게 디자인을 끝냈다는 느낌을 지울 수 없다. 뭔가 2% 부족한 게 느껴지는 글꼴이다.

샘물2 (custom):
  박 정만 님이 제작한 2*1*2벌 샘물 계열 글꼴로, 도깨비 조합 규칙도 너무 널널하기 때문에 자체 조합 테이블을 내장시켜 글꼴 파일의 크기를 4KB가 채 안 되게 줄였다. 정사각형 안에서 공간을 최대한 활용하다 보니 다른 샘물 계열 글꼴에 비해 글자가 좀 납작하다는 인상은 받는다. 현재 <날개셋> 한글 입력기의 내장 글꼴은 정 재민 님이 이 글꼴을 다듬어 굵기를 줄이고 옛한글 자모를 추가한 것이다.

굽은샘물 (custom):
  도깨비 조합 규칙을 쓰는 공개 글꼴인데 실제로 사용되는 벌수는 3*1*2벌밖에 되지 않기 때문에 자체 조합 테이블 방식으로 파일 구조를 대체했다. 글자의 전반적인 느낌은 무척 깔끔하고 참신하지만 ㅔ, ㅐ, ㅗ 같은 모음과 자음을 변별하기 어려운 점이 좀 아쉽다.

타자기 (custom):
  무려 2*1*1벌로, <날개셋> 한글 입력기가 제공하는 글꼴 중 구조가 가장 초단순하다. 아래아한글 1.x 수준의 옛한글 자모까지 일부 있음에도 불구하고 크기는 겨우 4KB밖에 되지 않는다.

굴림옛한글 (custom):
  트루타입 글꼴의 내부에 있는 옛한글 비트맵 자형을 추출한 것으로, <날개셋> 5.x가 지원하는 유니코드 5.2 옛한글을 거의 다 그것도 네모꼴 글꼴로 표현할 수 있는 유일한 글꼴이다. 물론 초중종 벌수는 6*2*4벌로, 도깨비보다도 벌 수가 적으며 글자가 전반적으로 좀 엉성하긴 하다.

유사굴림 (custom):
  다음 5.31 버전에서 추가될 예정인 글꼴로, "굴림체" 16픽셀을 얼추 조합형 글꼴로 본뜬 짝퉁이다. 현대 한글 11172자밖에 표현할 수 없지만 크기는 무려 40KB를 넘어서 "굴림 옛한글" 수준에 육박하는데, 이는 조합 테이블의 크기가 굉장히 크며 초성 하나, 모음 하나가 10여 벌, 20여 벌에 달하는 경우도 있기 때문이다. 가장 정교하고 복잡한 조합 테이블을 사용하는 글꼴이다.
다른 글꼴들은 초성은 겨우 ㄱㅋ, 종성은 ㄴ 정도만 따로 분리하여 그룹을 나누는 반면 이 글꼴은 거의 모든 자소들이 분할되어 있으며 자형 활용의 폭이 가장 크다. 가령 다른 글꼴들은 농과 논, 통과 톤에서 ㅗ의 위치가 다 같지만, 이 글꼴은 다 다르다. 그렇기 때문에 글자 하나의 완성도 하나는 이 글꼴이 가장 뛰어나다.

도깨비 방식,
그리고 도깨비보다 간단한 글꼴 내지 더 복잡한 글꼴.
<날개셋> 편집기는 한글 입력 방식뿐만 아니라 출력 방식도 과거와 현재의 만남의 장이 되고 있다.

Posted by 사무엘

2010/01/11 09:56 2010/01/11 09:56
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/77

더미

새로운 의약품이 개발되었을 때는 임상 실험을 차마 사람을 대상으로 할 수 없기 때문에 맨 처음에 동물을 상대로 실시한다. 사실 의학 내지 생명 공학을 연구하는 과정에서 실험용 흰쥐를 비롯해 적지 않은 동물들이 희생된다. 그래서 그런 연구소의 뒤뜰에는 동물 위령탑이 있을 정도이다.

그런데, 이쪽과는 완전히 다른 분야에서 또 인간에게 예상되는 위험을 대신 체험해 주는 존재가 있으니, 그것은 바로 더미(dummy)이다. 더미란 사람과 유사한 체구, 체중, 표면 재질을 갖추고 있는 마네킹 비슷한 인체 모형이다. 여기에다 온갖 센서들을 장착한 후 개발 중인 신차의 좌석에 곱게 앉혀 놓고 차를 충돌시킴으로써, 탑승자가 신체 부위별로 어떤 데미지를 받았는지, 생명에 지장은 없는지, 차 디자인이 안전 면에서 문제가 없는지를 연구진들은 꼼꼼히 분석하게 된다. 보통 시속 60km로 주행하다가 콘크리트 벽에 정면충돌하는 테스트가 가장 일반적인 형태 같다.

더미는 덩치는 옷 가게에 진열돼 있는 마네킹과 비슷하다. 그러나 용도는 그런 마네킹과는 근본적으로 완전히 다른 물건이다. 코스프레를 하는 일이 없으며 사람의 체중까지 흉내내어야 하기 때문에 마네킹보다 더욱 무겁다(지게차로 운반한다고 한다). 또한 대량 생산하는 물건이 아닌 데다 최첨단 센서 장비가 동원되다 보니 가격도 굉장히, 엄청 비싸서 한 개 가격이 억대에 육박한다고 한다. 쉽게 말해서 더미 하나의 가격이 거의 버스 한 대 가격이라는 뜻.

더미는 성인 남자, 임산부, 노인, 어린이, 아기 등 다양한 체구별 에디션(?)이 존재하며 이 한 세트가 일종의 더미 일가족을 구성한다. 실제로 자동차 회사의 연구소는 이런 더미 한 세트를 보유하고서 한 모델이 개발될 때까지 수십에서 무려 백수십 회에 이르는 충돌 테스트를 하게 된다. 한번 테스트용으로 사용한 더미는 강한 충격으로 인해 파손된 부품만 그때그때 교체하고서 거듭 재활용하는 게 일반적이나(가격의 압박), 심하게 손상된 더미는 어쩔 수 없이 폐기하고 새걸 구입하기도 한다.

한 가지 흥미로운 것. 충돌 테스트를 할 때 차를 어떻게 움직이는지가 궁금하지 않은가? 밖에서 차를 원격 무인 조종이라도 하는가 싶었는데 그건 아니고, 차는 가만히 서 있으면서 바닥의 무빙워크 같은 궤도가 위의 차를 날라서 벽에다 부딪히게 만든다고 한다. 궤도가 힘이 엄청 좋아야 할 것 같다.
쉽게 말해 실험 대상차는 시동을 걸지 않으며 바퀴가 굴러가지도 않는다는 뜻인데, 내가 옛날에 무슨 충돌 실험 동영상을 본 기억으로는 바퀴도 굴러갔던 것 같아서 좀 의아스럽다.

어쨌거나 교통사고란 정말 있어서는 안 될 비극이다. 그냥 순식간에, 너무나 허무하게 사랑하는 가족, 사회 구성원, 유능한 인재를 죽거나 불구 병신으로 만들며 그로 인한 사회적 손실은 이루 말할 수 없다. 특히 이놈의 음주운전 사고는 단순 과실치사가 아니라 고의성을 가미하여 살인 내지 살인 미수죄로 다스려야 하지 않나 생각해 본다.

Posted by 사무엘

2010/01/11 09:54 2010/01/11 09:54
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/76

thread local storage

컴퓨터 프로그램에서 뭔가 데이터를 저장할 기억 장소를 확보하는 방법은 크게 다음과 같은 세 가지이다.

먼저, 함수 안에서 선언하는 지역 변수이다. 지역 변수는 스택에다 할당되며, 그 함수와 사실상 일심 동체이기 때문에 거듭 실행되면 계속 스택을 점유하여 기억 장소도 계속 할당된다. 따라서 스레드 충돌 걱정을 할 필요도 없으며, scope을 벗어나면 소멸도 100% 자동으로 되기 때문에 memory leak가 생길 여지도 전혀 없다. 끼칠 수 있는 영향의 범위 자체가 가장 좁다.

그리고 전역/static 변수가 있다. 이들은 scope이 말 그대로 굉장히 정적이며, 프로그램 실행 기간 내내 살아 있고 프로세스 내부의 모든 스레드들이 공유한다. 잘 알다시피 static은 메모리에 저장되는 형태는 전역 변수와 완전히 같고, 접근성은 지역 변수와 같은 중간 존재이다.
이런 변수가 C++ 개체라면, 생성자나 소멸자 함수가 호출되어야 하는데 이는 main 함수의 실행을 전후하여 CRT 라이브러리가 알아서 해 준다.

마지막으로 heap에다 할당되는 동적 메모리가 있다. 이것은 가장 동적이고 자유로운 야생마 같은 형태의 메모리로, 프로그램 언어 차원에서 보장해 주는 scope이란 개념이 없다. 전적으로 프로그램이 양도 얼마든지 할당하고 아무 스레드에서나 해제 가능하다. 그 대신 C/C++에서 온갖 포인터 관련 버그, memory leak의 온상이 되는 존재이기도 하다.

그런데 멀티스레드 환경이 보편화하면서 첫째와 둘째의 또다른 형태의 중간에 속하는 scope이 필요해진 게 있으니, 바로 한 스레드 안에서만 global인 공간이다.
사실 표준 C 라이브러리조차도 멀티스레드 환경을 고려하지 않고 디자인되어 지금 문제되고 있는 요인들이 적지 않다.

함수의 실행 결과를 나타내는 에러 코드를 예전에는 그저 전역 변수 하나에만 집어넣으면 됐지만 멀티스레드 환경에서는 최소한 스레드마다 독립된 공간에 저장해야 한다.
strtok 함수는 예전에는 토큰 해석 위치를 그저 static 변수에다가 집어넣으면 됐지만, 이랬다가는 여러 스레드가 동시에 이 함수를 호출했을 때는 재앙을 각오하야 한다.
qsort 함수는 콜백 함수만 달랑 받지 콜백 함수에 따로 사용자가 지정한 데이터 따위를 넘겨 주지는 않는다. 결국 콜백 함수가 외부로부터 정렬 옵션 같은 걸 얻고자 한다면 전역 변수로부터 참고를 해야 하는데, 서로 다른 정렬 옵션으로 여러 스레드가 동시에 qsort를 호출하면 어떤 상황이 벌어지게 될까?

이런 기초적인 문제를 해결하기 위해 멀티스레드 운영체제는 thread local storage를 관리하는 기능을 제공한다. 윈도우 API에서는 TlsAlloc()으로 TLS 슬롯 번호를 하나 받아서 그 값을 전역 변수로 저장한다. (해제는 나중에 TlsFree()로) 그래서 TlsGetValue()와 TlsSetValue()에다가 아까 받은 TLS 슬롯을 넘겨줌으로써 machine word와 같은 크기의 정수/포인터 값을 읽고 쓰면 된다.

한 프로세스 안에서 동일한 슬롯 번호이지만, 이 함수를 호출하는 스레드가 무엇이냐에 따라 서로 제각기 독립된 값을 읽고 쓸 수 있음이 보장된다는 것이다. 스레드별로 공유해야 하는 값이 그냥 정수 하나라면 그 값을 바로 집어넣으면 되지만, 더 큰 영역의 메모리라면 따로 heap에다 할당한 메모리의 포인터를 집어넣으면 된다.

한 프로세스가 가질 수 있는 TLS 슬롯은 윈도우 95/NT4 시절에는 64개였다. 그러나 윈도우 2000/XP/비스타급에서는 수백, 1천 개가 넘어가도 괜찮게 바뀌었다. 나뿐만이 아니라 한 프로세스에 같이 로드되어 있는 다른 수십 개의 DLL들이 다 TLS 슬롯을 요청하기도 하기 때문에 TLS 슬롯 요청은 최소화하는 습관을 들여야 한다. TLS는 EXE보다도, 내가 생성하지 않은 스레드에 느닷없이 붙어서 돌아가야 하기도 하는 DLL을 만들 때 더욱 필요한 존재이다.

CRT 라이브러리의 DLL 에디션도 strtok 같은 함수를 구현하기 위해 TLS를 사용한다. 직전의 토큰 위치를 TLS 슬롯이 가리키고 있는 별도의 메모리에다 저장해 놓고 그때 그때 참고한다는 것이다.
또한 qsort처럼 콜백 함수가 사용할 데이터를 별도로 얻는 방법이 없는 함수를 사용하면서도 스레드 안전은 보장되게 코드를 짜야 할 때, 그 데이터를 TLS에다가 저장해 놓은 뒤 내가 짠 콜백 함수는 그 TLS를 사용하도록 만들 수도 있다.

TlsGet/SetValue()는 일종의 없는 scope을 새로 구현하는 함수이다. 그렇기 때문에 함수 실행 결과값을 기존 scope에 속하는 전역/지역 변수에다가 저장해 놓는다는 게 완전 무의미하다. 그러므로 콜백 함수가 TLS를 사용한다면 이 함수도 매번 무지막지한 빈도로 호출해야 한다. 따라서 이 함수는 다른 어떤 함수들보다도 성능에 초점을 맞춰 구현되어 있으며, 인자값의 검증을 거의 하지 않는다고 MSDN에 명시되어 있기도 하다.

물론 근본적으로 비주얼 스튜디오 2005에서 도입된 strtok_s는 TLS를 꺼낼 필요가 없이 토큰 위치를 아예 별도의 인자로 넘겨준 포인터에다 저장하도록 프로토타입이 바뀌어, 문자열을 중첩적으로 토큰화할 수도 있게 됐다.
그리고 qsort_s는 콜백 함수에다 넘겨줄 데이터를 별도로 같이 지정도 할 수 있다. 이렇게 하는 게 전역 변수급(TLS 포함) 메모리의 사용을 줄이고, 가능한 한 함수 인자와 지역 변수만 사용함으로써 모듈 사이의 독립성도 높이는 좋은 방법일 것이다.

DLL의 함수를 매번 LoadLibrary, GetProcAddress, FreeLibrary로 퍼 와서 쓰는 게 불편하기 때문에 import library가 존재하듯이, TLS도 비주얼 C++의 컴파일러 확장을 이용하여 좀더 쉽게 사용하는 방법이 있긴 하다. __declspec(thread)로 선언된 변수는 컴파일되는 바이너리의 내부에 .data, .text 처럼 섹션이 .tls라고 하나 더 생기고 거기에 보관된다. 하지만 이건 운영체제 관점에서 오버헤드가 굉장히 크고 옛날 운영체제에서는 동작하지 않기도 해서 잘 쓰이지 않는다.
#pragma data_seg로 섹션을 하나 더 만들어서 share 속성을 주어, 메모리 맵을 쓰지 않고 모든 프로세스에서 공유되는 메모리 영역을 만드는 것과 비슷한 차원인데, 물론 사용되는 기술 계층은 서로 차이가 있다.

우리가 다른 프로세스에서 멀티스레드로 동작하는 DLL을 만들고 있는데 우리 프로그램이 스레드마다 꽤 복잡한 C++ 오브젝트라든가(별도의 메모리 내지 리소스의 할당/해제가 필요한) 대용량 오브젝트를 운영해야 한다면 어떻게 해야 할까? TLS 슬롯에는 그 포인터밖에 집어넣을 수 없으며 메모리는 별도로 할당해야 한다. 그러나 디버거 쪽 훅을 설치하지 않는 이상 스레드의 생성, 소멸을 일일이 다 감시할 수는 없다. 그 대신 스레드마다 새로 생성된 TLS 슬롯의 초기값은 언제나 0임이 보장되기 때문에 오브젝트의 생성은 TlsGetValue의 값을 매번 검사하여 NULL일 때 하면 된다.

소멸은 약간 주의해야 한다. 프로세스의 실행 중에 스레드가 하나 실행이 끝났다면 DllMain에 DLL_THREAD_DETACH 통지가 오기 때문에 그때 우리 스레드 TLS 슬롯이 가리키는 포인터를 해제해 주면 되나, 문제는 모든 스레드의 소멸에 대해 일일이 이런 통지가 오지는 않는다는 것이다. primary thread의 실행이 종료됨으로써 DLL_PROCESS_DETACH 한 방으로 끝인 경우도 빈번하기 때문이다.

한 스레드가 여타 스레드의 모든 TLS 슬롯 값들을 enumerate하는 방법은 윈도우 API에 존재하지 않는다. 그렇기 때문에 각 스레드가 갖고 있는 포인터들은 별도의 전역 변수 링크드 리스트 같은 데에 별도로 관리하고 있다가 프로세스가 단번에 종료되면 이들을 한꺼번에 해제도 해 줘야 한다. 어차피 프로세스가 종료되는 마당에 memory leak 정도야 문제될 게 없지만, inter-process한 커널 오브젝트처럼 "cleanup"이 반드시 제때에 이루어져야 하는 자원도 있을 수 있기 때문이다.

물론 가장 이상적인 경우는 DLL을 만드는 우리가 매 스레드별로 Init 내지 Uninit 함수를 만들어서 우리 DLL을 사용하는 응용 프로그램이 스레드 실행의 시작과 종료를 알려 주는 것이다. 이렇게만 하면 모든 논란이 일축된다.

Posted by 사무엘

2010/01/11 09:53 2010/01/11 09:53
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/75

스레드 동기화


컴퓨터가 충분히 발전하여 오늘날의 운영체제 시스템 개념을 실현하게 된 것은 중앙 처리 장치가 최소한 32비트로 커지고부터이다. 보호 모드, 가상 메모리, 스레드 같은 것들. 4GB 정도는 돼야 주소 공간이 아쉬운 대로 넓다고 말할 수 있기 때문이다. 아무리 메모리 부족하고 열악한 임베디드 기기라 해도, 일단 최소한 디스플레이가 있는 general-purposed 컴퓨터라면, 16비트 시절의 원거리/근거리 포인터 같은 기법을 재도입할 정도로 열악하지는 않다.

물리 메모리와 가상 메모리의 대응을 운영체제가 CPU 차원의 지원으로 즉각 수행할 수 있게 되고 시분할 동시작업도 하드웨어 차원에서 할 수 있게 된 것은 소프트웨어 개발자에게 매우 큰 편의와 잠재성을 제공하게 되었다. 이를 입증하는 윈도우 3.1과 95의 큰 차이는 마우스 포인터 모양만 봐도 알 수 있다. 옛날에는 프로그램을 로딩하고 있을 때는 마우스 포인터가 완전 모래시계로 바뀌고 시스템 전체가 응답 불가 상태였지만, 지금은 화살표 오른쪽에 작은 모래시계가 붙고 시스템은 여전히 사용 가능하다(물론 좀 느려지기는 하지만). 또한, 모래시계 포인터는 해당 프로그램 안에서만 모래시계이지 다른 응용 프로그램에서는 여전히 화살표이다. 이른바 선점형 멀티태스킹 덕분이다.

단일 스레드 환경에서 사용자의 입력도 받으면서 작업도 동시에 수행하려면 타이머로 정말 찔끔찔끔 작업을 하거나, 작업 루틴 내부에서 수시로 입력을 체크(윈도우 API로는 PeekMessage 같은)해 주어야 했다. 효율은 효율대로 떨어지고 코드는 더욱 복잡해질 수밖에 없었다. 멀티스레드에서는 그런 번거로운 짓을 할 필요가 없다. 하지만 단일 스레드에서 전혀 신경쓸 필요가 없던 또다른 걱정거리가 생겼는데, 그것은 바로 스레드 동기화이다.

실행되고 있는 여러 스레드에 CPU 시간이 어떻게 분배되는지는 정말 전혀 예측할 수 없다. 심지어 a++; 같은 간단한 문장도 기계어로는 두세 개로 번역되는데 이 명령을 수행하던 도중에 스레드의 context가 바뀔 수가 있다. 여러 스레드가 동일한 데이터에 동시에 접근하여 값을 읽고 쓰다 보면, 다른 스레드에 의해 계산 전 값이 덮어써지거나, 아직 처리가 덜 끝난 중간 상태가 다른 스레드에 의해 뒤엉켜 버릴 수가 있다.

쉽게 말해서 a=0이고 a의 값을 1 증가시키는 스레드를 100개를 만들어서 아무 통제도 없이 이들을 동시에 실행시켰다고 가정해 보자. 그렇다면 스레드 실행이 모두 끝난 후 a의 값이 100이 되어 있을까? 천만의 말씀이다. 한 스레드가 a의 값이 0임을 인지만 한 찰나에 다른 스레드로 context가 넘어가고, 그 스레드 역시 a의 값을 0으로 인식하게 된다. 그러면 두 스레드는 모두 1이라는 값을 기록하게 되고.. 그렇다면 a는 도저히 100이 될 수가 없어짐이 명확하다. a++ 같은 지극히 단순한 연산이 이러한데 하물며 링크드 리스트나 트리 같은 복잡한 자료 구조를 변형하는 루틴에 여러 스레드가 동시에 접근한다면 어떤 재앙이 벌어질까?

멀티스레드 환경에서는 필연적으로 한 데이터를 여러 스레드가 공유하게 된다. 문서를 입력 받는 GUI 스레드와, 내부적으로 문서의 맞춤법 검사를 하는 스레드. 작업을 진행하는 스레드와 그로부터 작업 상황을 출력하는 스레드 등. 컴퓨터는 사용자가 프로그램을 짜 준 작업 중 어느 구간이 반드시 원자성이 보장되어야 하는지, 어느 구간이 반드시 여러 스레드들이 순차적으로 실행되어야 하는지를 알지 못한다. 이는 사용자가 지정해 주어야 하며, 운영체제는 스레드 동기화를 위한 여러 기법들을 제공하고 있다.

아무 통제 없는 무법천지인 멀티스레드 환경만으로는 프로그래머가 뭔가 의미 있는 작업을 하는 게 불가능하기 때문이다. 흔히 멀티스레드 환경을 여러 사람이 사용하는 한 화장실에다 비유하는데 무척 재미있고 적절한 비유 같다. 사람은 바글바글한데 화장실 문을 잠글 수 없다면 누가 감히 용변을 볼 수 있을까?

먼저, 여러 스레드들이 공유하여 시시때때로 값을 바꿀 수 있는 변수라면 C/C++의 경우 volatile로 선언하는 것이 필수이다. 고급 언어로 한 메모리 영역으로 표현되는 변수라 할지라도, 기계상으로는 메모리와 레지스터라는 차이가 존재할 수 있기 때문이다. 아울러 멀티스레드를 고려하다 보면 프로그램 모듈간의 독립성도 결국 고려하지 않을 수 없게 된다. 당장 쓰기 쉽다고 습관적으로 남발하던 전역/static 변수들은 멀티스레드 환경에서는 재앙으로 돌아올 가능성이 높다.

윈도우 운영체제는 정수 변수값을 1 증가하거나 감소시키는 것을 원자성이 보장되게 수행해 주는 InterlockedIncrement/Decrement라는 함수를 제공한다. 앞서 말했듯이 심지어 a++; 같은 간단한 연산조차도 컴퓨터에서는 CPU 한 사이클로 해결되지 않으며, 연산 수행 도중에 스레드 context가 바뀌고 결과가 꼬일 수 있다. 여러 스레드가 동시 접근할 수 있는 COM 오브젝트를 만든다면 reference count를 관리하는 함수를 이 함수를 이용해서 만들면 될 것이다. 고작 숫자를 1 더하고 빼는 것밖에 없지만 이것이 운영체제가 제공하는 가장 간단한 형태의 스레드 동기화 기능이라고 볼 수 있다.

이것보다 좀더 복잡하고 임의적인 루틴에 동기화 제동을 걸고 싶다면 임계 구간(critical section)이 좋은 선택이 될 수 있다. 크리티컬 섹션 오브젝트를 전역 변수로 선언하여 초기화해 준 후, 한 번에 한 스레드만이 차례대로 접근해야 하는 구간의 앞에 EnterCriticalSection을 해 주고, 끝에 LeaveCriticalSection을 해 주면 된다. 방법도 쉽다. 아까의 Interlocked* 함수는 크리티컬 섹션이 가미된 a++ 연산이라고 보면 된다.

이 정도면 다 된 것 같은데 동기화와 관련해서 또 필요한 게 있을까? 크리티컬 섹션은 간단하고 쓰기 쉽고 성능도 매우 좋은 반면, 타 스레드가 임계 구간을 빠져나올 기미가 안 보이더라도 한없이 기다리는 수밖에 없다. 또한 동일한 코드에 대한 스레드 접근만 제어할 수 있지, 다른 스레드(심지어 다른 프로세스)가 임의의 다른 작업을 끝낼 때까지 나의 스레드 실행을 멈추는 식으로 제어를 할 수는 없다.

이쯤 되면 그림이 나온다. 스레드 동기화 기능들을 수행하는 중요한 역할 중 하나는 busy waiting을 없애는 것이다. XT, 286 시절에는 컴퓨터 실행을 좀 느리게 하기 위해서 for i=1 to 5000: next 같은 문장을 썼지만 지금은 그건 큰일 날 짓이다. 자발적으로 일정 시간 CPU 시간을 내어 주고 프로그램 실행을 멈추는 Sleep 같은 운영체제 함수를 써야 한다. 어떤 스레드가 작업을 끝낼 때까지 쉬는 것도, while(bProcessing); 이런 식으로 수도 없이 뺑뺑이를 도는 polling은 절대 피해야 한다.

그렇기 때문에 일정 조건이 만족될 때까지 스레드를 CPU의 사용 없이 자동으로 기다리게 하는 함수가 있으며 이와 관련된 스레드 동기화 오브젝트들이 커널 차원에서 제공된다. “어떤 스레드가 임계 구간을 빠져나갈 때까지”란, 그 조건의 subset일 뿐인 것이다.

커널 오브젝트는 단순 크리티컬 섹션보다는 느리다. 이를 사용하기 위해서는 user 모드와 kernel 모드 사이의 전환 overhead를 감수해야 한다. 하지만 이들은 쓰임이 훨씬 더 범용적이며, 단순한 변수가 아니라 핸들과 이름으로 식별하기 때문에 inter-process하며 시스템 전체에서 통용이 가능하다. (이런 커널 오브젝트의 존재 여부로 프로그램의 중복 실행을 감지할 수도 있을 정도이다.) 크리티컬 섹션은 스레드의 waiting이 아주 implicit하게 일어나지만, 커널 오브젝트는 이를 WaitForSingleObject 같은 함수로 explicit하게 지정 가능하며 기다리는 한도를 제어할 수 있다. 또한 다른 커널 오브젝트들과 덩달아 함께 기다리게 할 수도 있다.

뮤텍스는 크리티컬 섹션의 커널 오브젝트 버전에 가깝고, 세마포어는 임계 구간에 들어갈 수 있는 스레드의 최대 개수를 지정할 수 있어서 뮤텍스보다 더욱 범용적이다.
한편 이벤트는 굳이 임계 구간이 아니더라도 사용자가 임의의 신호를 날려서, 그 신호를 기다리며 잠들어 있던 스레드를 깨울 수 있게 한 원초적이고 general-purpose한 동기화 수단이다.

결국 스레드 동기화 수단이 여럿 등장했는데, 구현 형태는 달라도 결국 여기에 적용될 수 있는 동사는 딱 둘.. ‘잠그기, 풀기’로 요약된다. 그래서 MFC는 이런 것들을 CSyncObject라는 클래스로 요약하여, Lock과 Unlock이라는 가상 함수로 공통 기능을 추상화해 놓고 있다.

참고로 이런 것뿐만 아니라 프로세스, 파일, 스레드 핸들 그 자체 같은 다른 커널 오브젝트들도 동기화 오브젝트에 해당하는 것이 여럿 있다. 그래서 해당 프로세스의 실행이 끝날 때까지, 혹은 스레드의 실행이 끝나고 파일 트랜잭션이 끝날 때까지 프로그램을 기다리게 하는 게 가능하다.

Posted by 사무엘

2010/01/11 09:52 2010/01/11 09:52
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/74

<날개셋> 한글 입력기가 기본 제공하는 텍스트 필터도 벌써 10 종류를 넘어섰군요.

매뉴얼에 나와 있는 대로, 텍스트 필터란, 일정한 텍스트 A가 있을 때 이것을 적당한 규칙대로 변형해서 B라는 텍스트를 만들어 주는 기능의 총칭입니다.
기본 제공되는 필터들은 기능의 성격에 따라 다음과 같은 다섯 그룹으로 분류됩니다.

※ 한글 입력과 관련된 것: 동작 방식이, 현재 사용 중인 한글 입력기 설정에 따라 달라집니다. 사실 텍스트 필터라는 개념 자체가 처음에 한글 입력기 기능의 자동화를 위해 도입된 것이기도 합니다.

  - 문자열을 글자판 입력으로: '한글'을 mfskgw(세벌식) 또는 gksrmf(두벌식)으로 바꿔 줍니다. 한글을 입력하는 데 필요한 영타를 재현하는 기능을 이렇게 필터라는 자동화 기능에다가 접목시켰습니다. 한글을 암호화(?)를 비롯해 다양한 형태로 가공하는 데 이 필터를 활용할 수 있습니다.
한글 로마자 입력 방식을 쓰고 있다면 이 기능은 한글을 얼추 로마자 표기법 형태로 바꿔 줄 수도 있습니다. 두벌식의 경우, 모호성이 발생하여 연속 입력이 안 되는 지점을 찾아내는 기능도 갖추고 있습니다.

  - 글자판 입력을 문자열로: 위 기능의 역변환입니다.
  - 한글 낱자 재결합: 한글을 현 입력기의 오토마타 설정대로 재결합하는 기능으로, 현재 오토마타 설정에 따라 한글을 모아쓰기와 풀어쓰기(또는 반풀어쓰기) 등 다양한 형태로 변환할 수 있습니다. 또한 한글에서 초성, 중성 같은 특정 성분만 남길 수도 있지요. 한글 입력 오토마타 알고리즘을 키보드를 일일이 두들길 때뿐만 아니라 자동화, 일괄 처리 용도로도 활용할 수 있습니다.

※ 한글 형태 변환과 관련된 것: 컴퓨터에서 한글은 여러 가지 형태로 표현될 수 있습니다. 호환용 낱자도 있고, 글자마디도 있고, 소위 첫가끝 영역도 있습니다. 이것은 어떤 점에서는 번거롭지만 어떤 점에서는 마치 memory hierarchy처럼 각 계층별로 장단점이 있으며 어쩔 수 없이 필요한 귀결이기도 합니다. 한글의 표현 형태를 변환하는 것도 텍스트 필터가 해야 하는 중요한 임무 중 하나입니다.

  - 한글 낱자 종류 바꾸기: <날개셋> 한글 입력기가 사용하는 첫가끝 낱자와(초-종성 구분도 되는), 일반적으로 운영체제에서 통용되는 호환용 낱자 사이를 변환합니다.
  - 한글 형태 정규화: 한글을 표현 가능한 가장 상위 계층으로 최적화하거나, 무조건 다 첫가끝 낱자로 풀어 써 줍니다. U+AC00 하나로 표현 가능한 '가'도 U+1100, U+1161로 풀어 주는 식이죠. 풀어 쓴 형태는 모든 한글에서 ㅏ를 ㅓ로 바꾸는 식으로 낱자 단위의 정밀한 일괄 처리를 할 때 필요할 것입니다.

※ 한국어 관련: 한글뿐만 아니라 한국어의 특성까지 가미하여 간단한 자동화 처리가 가능한 기능을 필터로 엮었습니다.

  - 한글을 소리나는 대로: "국밥"을 "국빱"으로, "국력"을 "궁녁"으로 바꿔 주는 매우 흥미로운 기능입니다. 한글 표기에는 반영되어 있지 않은 음운 현상을 표현하기 위해 별도의 hint 부호도 4종류 도입했습니다.
  - 숫자를 한글로: 300을 "삼백"으로, 45를 "사십오"로 바꿔 줍니다.
  - 한자를 한글로: 한자를 한글 독음으로 일괄 치환합니다. 아래아한글에도 있는 기능이죠.
  - 정렬: 한글의 모든 표현 계층을 감안하여 sorting 기능을 제공합니다. 아래아한글처럼 초-중-종 순이 아닌 역순 비교도 가능하며, 중복 항목을 제거하는 기능도 있어서 유용할 것입니다.

※ 문자 단순 기계 치환 관련: 여기부터는 이제 한글, 한국어하고는 그다지 관련이 없는 단순 편의 기능입니다.

  - 대소문자 바꾸기, 전각/반각 바꾸기: 에디터가 제공하는 제일 고전적인 필터 기능이고 self-explanatory하므로 더 이상의 자세한 설명은 생략.
  - 빈 줄 제거: 공란밖에 없는 빈 줄을 제거하고 줄 끝의 공란도 제거해 줍니다. 개인적으로 무척 빈번하게 유용하게 쓰는 필터.
  - 일괄 치환: 주어진 텍스트 블록 내에서 여러 "바꾸기" 작업을 일괄 수행합니다. 에디터의 기존 "찾기-바꾸기" 기능으로는 수행하기 힘든 A <-> B 맞바꾸기도 한번에 할 수 있으며, 특히 줄바꿈 문자도 찾거나 바꾸는 문자열의 일부로 지정할 수 있기 때문에 줄 앞뒤로 문자를 추가하거나 줄 삭제, 탭을 줄바꿈으로 바꾸는 기능도 수행할 수 있게 됩니다.

※ 시스템 인코딩 관련: 운영체제가 제공하는 다국어 쪽 API를 사용해서 문자 종류나 인코딩 관련 변환을 수행합니다.

  - 인코딩 변환: 인코딩이 잘못 지정되어 깨진 문자를 변환합니다. 컴컴컴컴 -> ────────, ´eCN¹I±¹ -> 대한민국 등.
  - 시스템 언어별 변환: 히라가나 <-> 카타카나 변환, 번체 <-> 간체 한자 변환 등을 수행할 수 있습니다. 대소문자 변환도 A~Z뿐만 아니라 유럽어 추가 알파벳에 대해서도 수행 가능하며, 알파벳의 쓰임이 다른 터키어 같은 언어에 맞는 변환을 할 수도 있습니다.
  - 코드 번호로 변환: 글자를 가 -> ACO0 같은 유니코드 번호 또는 B0A1 같은 특정 인코딩의 코드 번호로 풀어 주거나 역변환을 합니다. C언어 내지 HTML과 호환되는 접두사를 붙일 수 있으며, 이 기능을 이용하여 %AC%BD 같은 URL의 의미를 해독할 수도 있게 됩니다.

Posted by 사무엘

2010/01/11 09:51 2010/01/11 09:51
Response
A trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/72

TTF의 글립 개수 제한

오늘날 운영체제의 표준 글꼴 포맷으로 널리 쓰이고 있는 TTF 내지 OTF는 내부적으로 쓰는 각종 구조체들이 기술하는 글립의 영역 크기가 16비트로 제한되어 있다.

이것은 TTF 파일이 제정되던 초창시에는 아주 넉넉하고 인심 쓴 공간이었다. 겨우 8비트 크기의 코드 페이지에 맞춰진 글꼴밖에 없던 서양에서, 그나마 “수천 자의 2바이트 한자를 써야 하는 동아시아 문자권”까지 국제화 차원에서 고려한답시고 크기를 넓힌 게 16비트였다. 무슨 포스트스크립트 글꼴은 그것마저 지원 안 돼서 한글 글꼴은 여러 파일로 나눠서 표현해야 하지 않았던가. 쓸데없이 비트 수가 크면, 쓰는 영역에 비해 불필요한 0만 뒤에 잔뜩 달라붙고 글꼴 래스터라이저를 더욱 ‘무겁게’ 만들게 된다.

하지만 지금은 시대가 달라졌다. 아무리 작은 임베디드 기기라도, 일단 사람과 직접적인 의사 소통을 하는 기계의 CPU는 일단 최하 32비트는 기본으로 먹고 들어간다. 실용적으로 가장 적합하면서도 가상 메모리라든가 현대적인 운영체제 기본 개념을 제대로 구현할 수 있는 최소한의 CPU 규모가 32비트가 아닌가 한다.

메모리 자원은 넉넉해지고 국제화의 중요성은 엄청 커졌다. 그래서 한컴바탕이라든가 Arial Unicode MS처럼, 모든 유니코드 영역 글꼴을 모두 담고 있는 글꼴의 필요성이 대두되고 있다.

아직 모든 문자가 16비트 안의 BMP에 있던 유니코드 2~3.0 시절까지는 그럭저럭 별 문제 없었고 6만 5천여 개라는 글립 개수 제한은 현실적으로 별 영향이 없었다. 하지만 이제 유니코드가 surrogate 영역까지 쓰고 집합 크기가 16비트 크기를 넘어서면서, 이제 단일 글꼴에다 유니코드 전영역 문자를 담을 수가 없어져 버렸다.

더구나 이 16비트라는 크기는 글자 코드 단위가 아니라, 글립이라는 그림 단위이다. 한 코드 페이지에 해당하는 글자가 여러 글립을 차지할 수가 있다. 조합형 한글 글꼴처럼 한 글자를 여러 글립의 묶음으로 표현하는 글꼴이 있다면, 그렇게 부품 글립이 들어가는 자리를 글립 인덱스 상으로 제외해 줘야 한다. 아랍어처럼 한 글자가 상황에 따라 여러 글립 중 하나로 달리 표현되는 문자가 있다면, 그런 것까지 고려해야 하기 때문에 실질적으로 표현 가능한 문자 개수는 더욱 줄어든다.

지금 컴퓨터의 두뇌가 32비트와 64비트 사이에서 달랑달랑 거리는 것처럼, 글꼴 쪽은 16비트 크기라는 글립 개수 한계를 어떻게 초월해야 할지 고민 중이다. 당연히 TTF 규격상으로 각종 구조체의 필드를 확장하고 새 버전 식별자만 부여하면 문제는 해결된다. 하지만 온갖 테이블들의 내부에서 바꿔야 하는 게 너무 많고 이 새로운 TTF는 이전의 어떤 운영체제/응용 프로그램에서도 인식 못 하는 듣보잡 포맷이 되고 말 것이다. 결국 문제는 호환성이다. =_=;;

Posted by 사무엘

2010/01/11 09:49 2010/01/11 09:49
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/71

« Previous : 1 : ... 205 : 206 : 207 : 208 : 209 : 210 : 211 : 212 : 213 : ... 215 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/05   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Site Stats

Total hits:
2714462
Today:
1134
Yesterday:
1404