# Windows NT vs. Unix: 설계 비교

> Clean Markdown view of GeekNews topic #16692. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16692](https://news.hada.io/topic?id=16692)
- GeekNews Markdown: [https://news.hada.io/topic/16692.md](https://news.hada.io/topic/16692.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-09-10T10:33:19+09:00
- Updated: 2024-09-10T10:33:19+09:00
- Original source: [blogsystem5.substack.com](https://blogsystem5.substack.com/p/windows-nt-vs-unix-design)
- Points: 20
- Comments: 1

## Summary

NT와 Unix의 설계 차이를 비교하여 NT의 초기 설계가 얼마나 진보적이었는지를 설명합니다. NT는 처음부터 이식성, 다중 처리 지원, 호환성을 목표로 설계되었으며, 이는 Unix와의 주요 차이점입니다. NT의 객체 지향 커널, 통합 메모리 아키텍처, 비동기 I/O 인터페이스 등은 Unix보다 더 진보된 기능을 제공하지만, 오늘날 NT와 Unix 시스템 간의 차이는 크지 않으며, NT의 UI 비대함이 성능 저하를 초래합니다.

## Topic Body

- NT는 종종 "매우 진보된" 운영 체제로 평가받았지만 그 이유를 잘 몰랐음  
  - 2023년 말, 'Inside Windows NT' 1판을 읽고 NT와 Unix를 비교하기로 함  
  - NT(1993년 7월)와 당시 Unix 시스템(4.4BSD, 리눅스 1.0)의 설계를 비교한 것임  
  - Unix 전문가로서 NT는 잘 모르기에 NT의 차이점 위주로 서술함  
  - NT가 Unix보다 나은 점이 무엇인지, 그리고 여전히 그런지에 대한 질문을 다룸  
  
### 미션   
  
- Unix의 역사는 NT보다 훨씬 오래됨  
  - Unix 개발은 1969년에 시작되었고 주요 목표는 프로그래머에게 편리한 플랫폼이 되는 것이었음  
  - Unix는 Multics에서 영감을 받았지만, 단순성에 초점을 맞춰 Multics를 능가함  
  - 이식성과 멀티태스킹은 Unix 설계의 원래 목표는 아니었음: 이러한 기능은 몇 년 후 Unix의 많은 "포크"와 재발명에서 추가됨  
- Microsoft의 역사  
  - MS-DOS의 첫 번째 릴리스는 1981년 8월에 출시되었고, "레거시 Windows"(DOS 기반 버전)의 첫 번째 릴리스는 1985년 11월에 출시됨   
  - MS-DOS는 널리 성공했지만, Windows가 진정으로 중요해진 것은 1990년 5월 Windows 3.0부터였음  
  - Windows NT는 1989년에 구상되었고 1993년 7월 NT 3.1 릴리스로 세상에 모습을 드러냄  
- Microsoft의 이점  
  - NT의 설계는 Unix보다 20년 늦게 시작되어 Microsoft에 이점을 줌  
  - Microsoft는 이미 MS-DOS와 레거시 Windows 덕분에 큰 사용자 기반을 확보하고 있었음  
  - NT를 설계한 Microsoft 팀은 이러한 개발의 통찰력, 다른 운영 체제 개발 경험, 최신 기술에 대한 접근성을 가지고 있어 NT 제작에서 "달을 향해 쏘기"를 할 수 있었음  
  
### 커널   
  
- Unix는 Minix나 GNU Hurd와 같은 몇 가지 예외를 제외하고 모놀리식 커널로 구현되어 운영 체제가 제공하는 기능과 상호 작용하기 위한 시스템 호출 모음을 노출함  
- 반면 NT는 모놀리식 커널과 마이크로커널의 중간 형태임: 특권 구성 요소인 *executive*는 사용자 공간 *subsystems*에 모듈식 구성 요소 모음으로 자신을 표현함  
- 사용자 공간 subsystems는 애플리케이션이 사용하는 API(POSIX, OS/2 등)를 executive 시스템 호출로 "변환"하는 특수한 프로세스임  
- NT executive의 중요한 부분 중 하나는 HAL로, 머신의 하드웨어에 액세스하기 위한 추상 기본 요소를 제공하고 커널의 나머지 부분에 대한 기반으로 작용함  
  - 이 계층은 NT가 i386, Alpha, PowerPC를 포함한 다양한 아키텍처에서 실행될 수 있게 하는 핵심임  
  - 당시 Unix는 특정 아키텍처에 결합되어 있었음: Unix 개념은 이식 가능했지만 구현은 그렇지 않았음  
  - SunOS는 원래 Motorola 68000만 지원했고, 386BSD는 Intel 아키텍처로의 BSD 첫 포팅이었으며, IRIX는 Silicon Graphic의 MIPS 기반 워크스테이션용 Unix 변종이었음  
- NT executive의 또 다른 중요한 부분은 멀티프로세싱 시스템 및 선점형 커널에 대한 지원임  
  - 커널에는 무엇이 다른 것을 중단할 수 있는지 결정하기 위한 다양한 인터럽트 수준(BSD 용어로 SPL)이 있지만, 더 중요한 것은 커널 스레드가 다른 커널 스레드에 의해 선점될 수 있다는 점임  
  - 이는 오늘날 모든 고성능 Unix 시스템이 하는 것이지만 많은 Unix가 시작한 방식은 아님  
  - 이러한 시스템은 선점이나 멀티프로세싱을 지원하지 않는 커널로 시작하여 사용자 공간 멀티프로세싱 지원을 추가한 다음 커널 선점을 추가함  
  - 마지막 단계가 가장 어려운 단계이며 FreeBSD 5.0 사가 난관을 설명함  
  - 따라서 NT가 처음부터 올바른 기반으로 시작한 것은 흥미로움  
  
### 객체   
  
- NT는 객체 지향 커널임  
  - Unix도 그렇다고 생각할 수 있음: 프로세스는 struct로 정의되고 파일 시스템 구현은 vnode("가상 노드", inode와 혼동하지 말 것)를 다룸  
  - 그러나 이는 NT가 하는 것과 정확히 같지 않음: NT는 이러한 모든 다른 객체가 시스템에서 공통 표현을 갖도록 강제함  
- 프로세스와 파일 핸들과 같은 이질적인 것들에 대해 의미 있는 추상화를 어떻게 제공할 수 있는지 의심할 수 있음  
- 실제로는 불가능하지만 NT는 이들 모두가 공통 객체 유형에서 상속되도록 강제했고, 놀랍게도 이는 몇 가지 좋은 특성을 가짐  
- **중앙 집중식 액세스 제어**  
  - 객체는 *object manager* 에 의해서만 생성되므로 정책을 시행할 코드의 단일 위치가 있음  
  - 권한 검사와 같은 의미론은 한 위치에서만 정의되고 시스템 전체에 균일하게 적용될 수 있어 강력함  
  - NetBSD도 이것이 좋은 아이디어라고 결론지었지만 2001년이 되어서야 Kernel Authorization(kauth) 프레임워크를 얻음  
- **공통 ID**  
  - 객체에는 ID가 있고 모두 단일 트리로 표현됨  
  - 이는 프로세스, 파일 핸들 또는 파이프에 관계없이 모든 객체에 대해 고유한 네임스페이스가 있음을 의미함  
  - 트리의 객체는 이름(경로)으로 주소 지정 가능하며 트리의 다른 부분은 다른 하위 시스템이 소유할 수 있음  
  - 예를 들어 트리의 일부는 마운트된 파일 시스템을 나타낼 수 있으며, 따라서 해당 하위 트리의 루트 노드를 탐색하면 파일 시스템이 경로의 나머지 부분을 해결하게 됨  
  - 이는 Unix 시스템의 VFS 계층과 유사하지만, VFS는 파일 시스템에 대해서만 다루는 반면 객체 트리는 *모든 단일 커널 객체*에 대해 다룸  
  - Unix는 `/proc/`, `/sys/` 등을 통해 비파일 객체 유형을 파일 시스템에 끼워 넣으려고 시도했지만, 이는 NT가 제공하는 것에 비해 사후 처리로 느껴짐  
- **통합 이벤트 처리**  
  - 모든 객체 유형에는 **signaled** 상태가 있으며, 그 의미는 각 객체 유형에 따라 다름  
  - 예를 들어 프로세스 객체는 프로세스가 종료될 때 signaled 상태로 전환되고, 파일 핸들 객체는 I/O 요청이 완료될 때 signaled 상태로 전환됨  
  - 이는 단일 wait 스타일 시스템 호출이 객체 그룹이 상태를 변경하기를 기다릴 수 있으므로 사용자 공간에서 이벤트 기반 코드(async 코드)를 작성하는 것이 매우 쉬워짐  
  - Unix 시스템에서 I/O 및 프로세스 완료를 동시에 기다리는 것은 고통스러움  
- 객체는 NT 고유의 구성 요소이며 NT가 지원하려는 모든 API에 잘 일반화되지 않음   
  - 예를 들어 POSIX 하위 시스템: POSIX에는 NT와 같은 객체 개념이 없지만 NT는 POSIX 애플리케이션과 어떤 종류의 호환성을 제공해야 함  
  - 이러한 이유로 POSIX 하위 시스템이 executive에서 객체를 할당하는 동안 해당 POSIX 엔터티를 나타내기 위해 자체 장부 기록을 유지하고 즉시 두 엔터티 간의 논리적 변환을 수행해야 함  
  - 반면 Win32 하위 시스템은 중개자 없이 클라이언트에 객체를 전달함  
  
### 프로세스   
  
- 프로세스는 NT와 Unix의 공통된 개체이지만 완전히 동일하지는 않음   
  - Unix에서는 프로세스가 트리로 표현되어 각 프로세스에는 부모가 있고 프로세스는 0개 이상의 자식을 가질 수 있음  
  - 그러나 NT에는 그러한 관계가 없음: 프로세스는 생성자로부터 리소스를 "상속"할 수 있지만 생성된 후에는 독립적인 엔터티임  
- NT가 설계되었을 당시 스레드는 흔하지 않았음:   
  - Mach는 1985년에 스레드를 통합한 최초의 Unix 유사 커널이었음  
  - 이는 다른 Unix가 이 개념을 나중에 채택하고 기존 설계에 맞게 수정해야 했음을 의미함  
  - Linux는 1996년 6월 2.0 릴리스에서 스레드를 각각 고유한 PID를 가진 프로세스로 표현하기로 선택했고, NetBSD는 2004년 2.0 릴리스까지 프로세스와 별개의 엔터티로 표현되는 스레드를 얻지 못함  
  - Unix와 달리 NT는 SMP 머신에서 고성능 컴퓨팅을 위해 스레드가 필수적임을 알고 처음부터 스레드를 지원하기로 선택함  
- NT에는 전통적인 Unix 의미의 시그널이 없음  
  - 대신 **alerts** 가 있으며 이는 커널 모드와 사용자 모드가 될 수 있음  
  - 사용자 모드 알림은 다른 객체와 마찬가지로 기다려야 하며 커널 모드 알림은 프로세스에 보이지 않음  
  - POSIX 하위 시스템은 커널 모드 알림을 사용하여 시그널을 에뮬레이트함  
  - 시그널은 프로세스 실행을 방해하는 방식 때문에 Unix에서 종종 사마귀라고 불렸음: 시그널을 올바르게 처리하는 것은 정말 어려운 노력이므로 NT의 대안이 더 우아한 것 같음  
- NT에서 최근에 흥미로운 개발은 **피코프로세스**의 도입이었음  
  - 이 기능이 추가될 때까지 NT의 프로세스는 상당히 무거웠음: 새 프로세스는 시작 시 주소 공간에 매핑된 NT 런타임 라이브러리 묶음을 얻음  
  - 피코프로세스에서 프로세스는 Windows 아키텍처와 최소한의 연관이 있으며, 이는 WSL 1에서 Linux 호환 프로세스를 구현하는 데 사용됨  
  - 어떤 면에서 피코프로세스는 기본 Windows 프로세스보다 Unix 프로세스에 더 가깝지만 WSL 2로의 이동으로 인해 2016년 8월부터 존재했음에도 불구하고 더 이상 많이 사용되지 않음  
- Windows의 보안 문제를 비난하는 만큼, NT는 시스템이 기본적으로 기능 기반 시스템으로 작동한다는 점에서 초기 인터넷 표준에 대한 고급 보안 설계로 시작함  
  - 로그온 후 시작되는 첫 번째 사용자 프로세스는 사용자 세션의 권한을 나타내는 커널로부터 액세스 토큰을 받으며, 프로세스와 하위 프로세스는 권한을 주장하기 위해 이 토큰을 커널에 제공해야 함  
  - 이는 프로세스가 단순히 식별자를 가지고 있고 커널이 프로세스 테이블에서 각 프로세스가 무엇을 할 수 있는지 추적해야 하는 Unix와 다름  
  
### 호환성   
  
- NT의 주요 목표는 레거시 Windows, DOS, OS/2 및 POSIX용으로 작성된 애플리케이션과 호환되는 것이었음  
  - 이에 대한 한 가지 이유는 기술적인 것으로, 이로 인해 시스템이 우아한 설계를 갖도록 강제되었음  
  - 다른 이유는 정치적인 것으로, NT는 IBM과 공동 개발되었고 NT는 결국 Windows가 되었음에도 불구하고 OS/2 애플리케이션을 **반드시** 지원해야 했음  
- 이러한 호환성에 대한 필요성으로 인해 NT의 설계는 Unix와 크게 달라졌음  
  - Unix에서는 사용자 공간 애플리케이션이 시스템 호출 인터페이스를 통해 커널과 직접 통신하며, 이 인터페이스가 Unix 인터페이스임  
  - C 라이브러리는 커널을 호출하기 위한 접착제를 제공하고 애플리케이션은 직접 시스템 호출을 실행하지 않지만 이는 사소한 세부 사항임  
- NT에서는 애플리케이션이 executive(커널)와 직접 통신하지 *않음*  
  - 대신 각 애플리케이션은 특정 보호된 *하위 시스템*과 통신하며, 이러한 하위 시스템은 NT가 호환되기를 원하는 다양한 운영 체제의 API를 구현함  
  - 이러한 하위 시스템은 사용자 공간 서버로 구현됨(NT "마이크로커널" 내부에 없음)  
  - Windows 애플리케이션에 대한 지원은 Win32 서버에서 제공하며, 이는 사용자가 직접 볼 수 있는 유일한 서버이기 때문에 특별함: 콘솔 프로그램과 DOS 터미널을 제어하며 성능상의 이유로 특정 권한을 가짐  
- 전통적인 Unix와 비교할 때 BSD와 Linux는 모놀리식 커널을 가지고 있기 때문에 NT의 설계는 매우 다름  
  - 이러한 커널은 사용자 공간 애플리케이션이 시스템과 직접 상호 작용하기 위해 활용하는 시스템 호출 인터페이스를 노출함  
  - 그러나 BSD는 모놀리식 커널 내에서 오랫동안 대체 **바이너리** 실행을 지원해 왔음: 이는 실행 중인 바이너리에 따라 사용자 공간에 다른 시스템 호출 테이블을 노출한 다음 해당 "외부" 시스템 호출을 커널이 이해하는 것으로 변환하는 방식으로 작동함  
  - Linux는 **personalities** 를 통해 이에 대한 제한된 지원도 제공함  
- BSD 접근 방식이 NT가 다른 시스템을 지원하는 방식과 매우 다르지만 WSL 1은 매우 유사하며 원래 정의된 용어로 하위 시스템이 아님  
  - WSL 1에서 NT 커널은 Linux 프로세스를 피코프로세스로 표시하고 거기에서 다른 시스템 호출 인터페이스를 노출함  
  - NT 커널 내에서 해당 Linux 관련 시스템 호출은 NT 작업으로 변환되어 BSD의 Linux 호환성과 마찬가지로 동일한 커널 내에서 제공됨  
  - 유일한 문제는 NT가 Unix가 아니기 때문에 Linux "에뮬레이션"이 까다롭고 BSD가 제공할 수 있는 것보다 훨씬 느리다는 것임  
  - WSL 2가 이 설계의 본질을 잃고 완전한 VM 설계로 갔다는 것은 유감임  
- NT 설계의 흥미로운 세부 사항  
  - NT 설계의 목표는 단일 셸에서 하위 시스템 간의 원활한 I/O 리디렉션을 허용하는 것이었음   
  - 하위 시스템은 *포트*를 통해 애플리케이션에 노출되며, 이는 NT 객체이고 Mach가 프로세스와 서버가 통신하는 방식과 유사함  
  
### 가상 메모리   
  
- NT는 Unix와 마찬가지로 모두 페이징이 있는 Memory Management Unit(MMU)에 의존하여 프로세스 간 보호를 제공하고 가상 메모리를 제공함  
  - 사용자 공간 프로세스의 페이징은 머신의 물리적 메모리 양보다 더 큰 주소 공간을 제공하는 일반적인 메커니즘임  
  - 그러나 NT를 당대의 Unix 시스템보다 앞서게 한 한 가지는 커널 자체도 디스크로 페이징 아웃될 수 있다는 것임  
  - 커널 전체가 페이징 가능하다면 페이징 아웃된 파일 시스템 드라이버의 코드가 필요한 커널 페이지 폴트를 해결하는 상황에 처하게 되겠지만, 커널의 상당 부분은 페이징 가능함  
  - 요즘에는 커널이 머신에 설치된 일반적인 메모리에 비해 작기 때문에 특별히 흥미롭지는 않지만 과거에는 모든 바이트가 소중했기 때문에 큰 차이를 만들었음  
- 요즘 우리가 가상 메모리와 페이징이 작동하는 방식을 당연하게 여기지만, 이는 NT가 설계되었을 때 큰 연구 분야였음  
  - 이전의 Unix 구현에는 파일 시스템과 가상 메모리에 대한 별도의 메모리 캐시가 있었고, SunOS가 이전 설계의 오버헤드를 줄이기 위해 통합 가상 메모리 아키텍처를 구현한 것은 1987년이 되어서였음  
  - 반면 NT는 처음부터 통합 메모리 아키텍처로 시작했음  
  - Unix에서 발견된 비효율성에 대한 통찰력이 있었고 NT 설계가 시작되기 전에 SunOS가 구현한 솔루션을 볼 수 있었기 때문에 이를 수행하기 쉬웠다고 말할 수 있음  
  - 그러나 이는 NT를 당시 다른 많은 운영 체제보다 "더 발전"시켰으며, NetBSD 1.6의 Unified Buffer Cache(UBC) 구현으로 2002년까지 다른 시스템이 따라잡지 못했음을 주목해야 함  
- NT와 Unix의 흥미로운 차이점은 공유 메모리를 관리하고 표현하는 방식임  
  - NT에서 공유 메모리 섹션은 객체이므로 다른 모든 객체와 정확히 동일한 액세스 유효성 검사를 받음  
  - 또한 단일 객체 트리의 일부이므로 다른 모든 객체와 동일한 방식으로 주소 지정할 수 있음  
  - Unix에서는 이 기능이 볼트로 고정되어 있음: 공유 메모리 객체는 다른 네임스페이스, 다른 모든 엔터티에 대한 다른 API를 가지므로 일반적인 권한이 적용되지 않음  
  
### I/O 서브시스템  
  
- 초기 버전의 Unix는 하나의 파일 시스템만 지원했음  
  - 예를 들어 BSD가 UFS 이상을 지원하기 위해 Virtual File System(VFS) 추상화를 얻은 것은 1990년 4.3BSD까지 이르렀음  
  - 반면 NT는 여러 파일 시스템을 허용하는 설계로 시작했음  
- 여러 파일 시스템을 지원하기 위해 커널은 어떤 식으로든 해당 네임스페이스를 노출해야 함  
  - Unix는 마운트 포인트를 통해 단일 파일 계층 구조에서 파일 시스템을 결합함: VFS 계층은 파일 시스템의 루트에 해당하는 노드를 식별하고 경로를 탐색할 때 해당 파일 시스템 드라이버에 요청을 리디렉션하는 메커니즘을 제공함  
  - NT는 표준 사용자 인터페이스에서 파일 시스템이 분리된 드라이브로 나타나더라도 유사한 설계를 가지고 있음: 내부적으로 executive는 파일 시스템을 객체 트리의 객체로 표현하고 각 객체는 경로의 나머지 부분을 구문 분석할 책임이 있음  
  - 해당 파일 시스템 객체는 사용자 공간에서 액세스할 수 있도록 DOS 드라이브로 다시 매핑됨  
  - DOS 드라이브도 참조하는 파일 시스템으로 I/O를 리디렉션하는 별도의 하위 트리 아래에 있는 객체임  
- NT는 결국 NTFS와 함께 출시되었음  
  - NTFS는 성능이 좋지 않다는 이유로 비난받는 것을 좋아하더라도(잘못된 주장) 당시로서는 정말 발전된 파일 시스템이었음  
  - NT의 I/O 하위 시스템은 NTFS와 결합하여 64비트 주소 지정, 저널링, 심지어 유니코드 파일 이름을 제공했음  
  - Linux는 1990년대 후반까지 64비트 파일 지원을 받지 못했고 2001년 ext3가 출시될 때까지 저널링을 받지 못했음  
  - 대체 내결함성 메커니즘인 Soft updates는 1998년까지 FreeBSD에 나타나지 않았음  
  - Unix는 파일 이름을 유니코드가 아닌 null 종료 바이트 배열로 나타냄  
- NT 출시 시 포함된 다른 기능으로는 디스크 스트리핑과 미러링(오늘날 RAID로 알려짐) 및 장치 핫 플러깅이 있음  
  - SunOS가 1990년대 초반부터 RAID 지원을 포함했기 때문에 이러한 기능은 새로운 것은 아니었지만, 흥미로운 점은 이들이 모두 원래 설계의 일부로 고려되었다는 것임  
  - 더 높은 수준에서 NT의 I/O 하위 시스템을 Unix보다 훨씬 더 발전시키는 것은 그 인터페이스가 본질적으로 비동기라는 사실이며 처음부터 그랬다는 것임   
  - 이를 관점에 두기 위해 FreeBSD는 1998년 FreeBSD 3.0까지 aio(7)에 대한 지원을 보지 못했고 Linux는 2002년 Linux 2.5까지 이를 보지 못했음  
  - 비동기 I/O에 대한 지원이 20년 이상 Unix 시스템에 존재했음에도 불구하고 여전히 널리 사용되지 않음: 이러한 API를 아는 사람은 거의 없고, 대다수의 애플리케이션은 이를 사용하지 않으며, 성능이 좋지 않음  
  - Linux의 io_uring은 비동기 I/O를 개선하는 비교적 최근 추가 기능이지만 보안 취약점의 주요 원인이었으며 널리 사용되지 않음  
  
### 네트워킹   
  
- 오늘날 인터넷은 어디에나 있지만 NT가 설계되었을 때는 그렇지 않았음  
  - Microsoft 생태계를 돌아보면 DOS 3.1(1987)은 FAT 파일 시스템에서 파일 공유를 위한 기반을 포함했지만 "OS" 자체는 네트워킹 기능을 제공하지 않았음: Microsoft Networks(MS-NET)라는 별도의 제품이 이를 수행했음  
  - Windows 3.0(1990)은 로컬 네트워크에서 기본적인 프린터 및 파일 공유를 허용하는 NetBIOS에 대한 지원을 포함했지만 TCP/IP에 대한 지원은 찾아볼 수 없었음  
- 반면 Unix는 인터넷 그 자체였음: 모든 기본 인터넷 프로토콜은 Unix로 그리고 Unix와 함께 작성되었음  
  - NT 설계 중에는 우수한 네트워크 지원을 고려하는 것이 중요했으며 실제로 NT는 네트워킹 기능과 함께 출시되었음  
  - 그 결과 NT는 인터넷 프로토콜과 기존 Microsoft 환경에서 사용되는 전통적인 LAN 프로토콜을 모두 지원했으며, 이는 기업 환경에서 Unix보다 NT를 앞서게 했음  
- 예를 들어 NT의 네트워크 도메인을 들 수 있음  
  - Unix에서 네트워크 관리자는 일반적으로 수동으로 머신 간에 사용자 계정을 동기화했음  
  - SunOS와 같은 시스템이 구현한 X.500 디렉터리 프로토콜(1988)과 Kerberos(1980년대)를 사용자 인증에 사용했을 수 있지만 이러한 기술은 특별히 간단하지 않았음  
  - 대신 NT는 시작부터 디렉터리 및 인증 기능을 통합한 도메인을 제공했으며, 이는 설정이 훨씬 쉽고 시스템에 내장되어 있기 때문에 회사 네트워크에서 "승리"한 것으로 보임  
- 동기화된 사용자 계정의 목표는 머신 간에 리소스, 주로 파일을 공유하는 것이며, 이렇게 할 때 권한을 나타내는 방법이 중요함  
  - 오랜 시간 동안 Unix는 각 파일에 대해 단순한 읽기/쓰기/실행 권한 집합만 제공했음  
  - 반면 NT는 처음부터 고급 ACL과 함께 제공되었는데, 이는 여전히 Unix에서 아픈 점임  
  - Linux와 BSD에도 이제 ACL이 있지만 시스템 간 인터페이스가 일관되지 않고 시스템 설계에 이질적인 추가 기능처럼 느껴짐  
  - NT에서 ACL은 객체 수준에서 작동하므로 모든 커널 기능에 일관되게 적용됨  
- 파일 공유에 대해 이야기할 때 네트워크 파일 시스템에 대해 이야기해야 함  
  - Unix에서 사실상 파일 시스템은 NFS였고 NT에서는 SMB였음  
  - SMB는 MS-NET 및 LAN Manager에서 상속되었으며 리디렉터라는 구성 요소를 통해 커널에 구현됨  
  - 본질적으로 리디렉터는 NFS가 Unix에 있는 것처럼 파일 작업을 트랩하고 네트워크를 통해 전송하는 "단순한" 또 다른 파일 시스템임  
- protobuf와 gRPC가 널리 사용되어 새로운 아이디어처럼 보일 수 있지만 오래된 아이디어에 기반을 두고 있음  
  - Unix에서는 주로 NFS를 지원하기 위해 1980년대 초반부터 Sun RPC를 사용했음  
  - 마찬가지로 NT는 자체 DSL(인터페이스 정의를 지정하고 원격 프로시저에 대한 코드를 생성하기 위해 MIDL로 알려짐)과 RPC 클라이언트 및 서버를 구현하기 위한 자체 기능을 통해 내장 RPC 지원과 함께 제공되었음  
- Unix 시스템은 임의의 드라이버 지원에 크게 주력하지 않았음: Unix 시스템은 일반적으로 특정 머신 및 공급업체와 결합되어 있었음  
  - 반면 NT는 "모든" 머신을 위한 OS가 되려고 했으며 소프트웨어 회사에서 판매되었으므로 다른 사람이 작성한 드라이버 지원이 중요했음  
  - 그 결과 NT에는 Network Driver Interface Specification(NDIS)이 제공되었는데, 이는 네트워크 카드 드라이버를 쉽게 지원하기 위한 추상화임  
  - 오늘날까지 제조업체에서 제공하는 드라이버는 Linux에서 그렇게 흔한 일이 아니며, 이로 인해 2000년대 초반에 Linux에서 WiFi 카드용 Windows 드라이버를 재사용할 수 있는 매우 인기 있는 셈인 ndiswrapper와 같은 흥미로운 장치가 생겨남  
- 마지막으로 NT와 Unix의 또 다른 차이점은 명명된 파이프의 구현에 있음  
  - 명명된 파이프는 Unix에서 로컬 구성 요소임: 동일한 머신에 있는 두 프로세스가 디스크에 지속적인 파일 이름으로 서로 통신할 수 있는 메커니즘을 제공함  
  - NT에는 이와 동일한 기능이 있지만 명명된 파이프가 네트워크를 통해 작동할 수 있음  
  - 공유 파일 시스템에 명명된 파이프를 배치하면 서로 다른 컴퓨터의 두 애플리케이션이 네트워킹 세부 정보를 걱정하지 않고도 서로 통신할 수 있음  
  
### User-Space   
- Configuration:   
  - NT는 레지스트리라는 데이터베이스에서 시스템 및 애플리케이션 구성을 중앙 집중화하여 레거시 Windows에서 사용되는 오래된 CONFIG.SYS, AUTOEXEC.BAT 및 수많은 INI 파일에서 벗어났음  
  - 이는 일부 사람들을 매우 화나게 만들었지만 결국 통합 구성 인터페이스는 모두에게 유익함: 지원할 단일 기반이 있기 때문에 애플리케이션을 작성하기가 더 쉬워지고 살펴볼 곳이 하나뿐이기 때문에 사용자가 시스템을 더 쉽게 조정할 수 있음  
  - 반면 Unix는 여전히 수십 개의 DSL과 일관성 없는 파일 위치로 인해 어려움을 겪고 있음  
  - 구성 파일을 지원하는 각 프로그램에는 자체 구문이 있으며, 프로그램이 읽는 위치를 아는 것은 어렵고 항상 잘 문서화되지는 않음  
  - Linux 생태계는 XDG 및 dconf(이전에는 GConf)를 통해 NT와 유사한 접근 방식을 추진했지만 데스크톱 구성 요소는 이러한 기술을 독점적으로 사용하는 반면 시스템의 기본 구성 요소는 이를 채택하지 않아 일관성 없는 엉망진창을 남김  
- Internationalization:  
  - Microsoft는 이미 전 세계에 Windows 3.x를 출시하고 있는 대기업으로서 지역화가 중요하다는 것을 이해하고 NT가 처음부터 이러한 기능을 지원하도록 만들었음  
  - 이를 UTF 지원이 1990년대 후반까지 나타나기 시작하지 않았고 선택적 gettext 추가 기능을 통해 다른 언어를 지원한 Unix와 대조해 볼 것   
- C 언어:  
  - FreeBSD 및 NetBSD와 같은 Unix 시스템이 한동안 꿈꿔 온 한 가지는 더 안전한 방식으로 커널을 구현하기 위해 자체 C 방언을 고안하는 것임  
  - 이는 GCC 전용 확장에 의존하는 Linux를 제외하고는 어디에도 가지 않았음  
  - 반면 Microsoft는 C 컴파일러를 소유하는 특권을 가지고 있었으므로 Microsoft C로 작성된 NT에서 이를 수행했음  
  - 예를 들어 NT는 소프트웨어 및 하드웨어 예외를 처리하기 위해 try/except 절을 추가하는 기능인 Structured Exception Handling(SEH)에 의존함  
  - 이것이 큰 장점이라고는 말하지 않겠지만 실제로 차이점임  
  
### 결론  
- NT는 출시 당시 획기적인 기술이었음  
- 위에서 설명했듯이 오늘날 시스템 설계에서 당연하게 여기는 많은 기능이 NT에는 처음부터 존재했지만, 거의 모든 다른 Unix 시스템은 시간이 지남에 따라 그러한 기능을 천천히 얻어야 했음  
- 그 결과 이러한 기능은 Unix 철학과 항상 원활하게 통합되지는 않음  
- 그러나 오늘날 NT가 Linux나 FreeBSD보다 진정으로 "더 발전했는지"는 분명하지 않음   
  - NT는 시작부터 더 견고한 설계 원칙과 동시대의 운영 체제보다 더 많은 기능을 가지고 있었지만, 요즘에는 차이가 모호함  
  - 즉, NT는 발전했지만 현대 Unix만큼 상당히 더 발전하지는 않았음  
- NT에 이러한 모든 견고한 설계 원칙이 있음에도 불구하고 UI의 비대화로 인해 설계가 빛을 발하지 못한다는 점이 실망스러움  
  - 초강력 머신에서도 OS의 느린 속도는 목격하기 고통스러울 수 있으며 심지어 이 OS의 종말로 이어질 수도 있음  
  
### GN⁺의 정리  
  
- 이 글은 NT와 Unix의 설계 차이를 비교하여 NT의 초기 설계가 얼마나 진보적이었는지를 설명함  
- NT는 처음부터 이식성, 다중 처리 지원, 호환성을 목표로 설계되었으며, 이는 Unix와의 주요 차이점임  
- NT의 객체 지향 커널, 통합 메모리 아키텍처, 비동기 I/O 인터페이스 등은 Unix보다 더 진보된 기능을 제공함  
- 그러나 오늘날 NT와 Unix 시스템 간의 차이는 크지 않으며, NT의 UI 비대함이 성능 저하를 초래함

## Comments



### Comment 28763

- Author: neo
- Created: 2024-09-10T10:33:19+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=41490290) 
- NT 커널은 훌륭하지만 오래된 설계임
  - Windows OS는 NT 커널 위에 많은 구식 요소가 쌓여 있어 문제 발생
  - Microsoft는 Win32와 MS-DOS 패러다임에서 벗어나 NT 기반의 새로운 OS 설계를 고려해야 함

- NT와 Unix의 가장 큰 차이점은 드라이버 접근 방식임
  - NT는 Windows 3.x/95/98의 드라이버 문제를 해결하기 위해 설계됨
  - Unix는 드라이버를 고신뢰성 구성 요소로 간주하며 커널 개발자가 작성함

- 현대 WinNT에서는 Direct3D가 커널의 필수 부분임
  - D3D11은 GPU 없이도 사용 가능하며, WARP라는 소프트웨어 대체 기능 제공
  - Linux에는 이와 유사한 기능이 부족함

- NT 커널은 프로세스가 아닌 스레드를 실행함
  - 스레드는 몇 밀리초 내에 생성 가능하며, 프로세스는 무겁게 작동함
  - NT의 역사는 VMS의 기본 원칙에 뿌리를 두고 있음

- WindowsNT는 초기에는 Linux보다 훨씬 더 잘 설계된 시스템이었음
  - NT는 Win32, OS/2, POSIX를 실행할 수 있었음
  - POSIX는 미국 정부의 대형 소프트웨어 계약을 위해 추가되었으나, 이후 관심을 잃음

- NT는 세 번째 시스템으로서 두 번째 시스템 증후군을 피함
  - OS/2는 기술적으로 잘못된 문제를 해결했으며, 조직적으로도 실패함
  - NT는 Windows XP까지 널리 사용되지 않았음

- 개발자 관점에서 Windows와 Linux의 차이점이 있음
  - 명령줄과 글로빙 방식에서 Windows가 더 우수함
  - Win32의 wchar_t 사용은 문제임

- NT 커널은 우아함을 가지고 있지만, 오픈 소스가 아님
  - 다른 사용자 공간과 데스크탑 환경을 가진 Windows는 흥미로울 것임

- Linux의 FUSE와 같은 융합이 있었음
  - Win NT의 파일 시스템 접근 방식은 많은 파일 시스템 작업을 매우 느리게 만듦
  - Microsoft는 WSL1을 포기하고, SQLLite나 ZIP 파일 같은 컨테이너를 사용함
