C. BSD UNIX

BSD UNIX에 대해 알아보자.

C.1. UNIX History

UNIX의 최초 버전은 1969년에 개발되었다. 이후 데니스 리치가 참가하였다. 이들은 C 프로그래밍 언어를 만들기도 하였다. UNIX가 개발되면서 이는 Bell 연구소에 폭넓게 쓰이고 다른 대학들에도 확산되었다. 1978년에는 버전 7이 배포되었다.

C.1.1. UNIX Support Group

버전 8은 스트림 입출력 시스템 기능을 포함하였다. UNIX 지원 그룹은 대개 AT&T 내에서 UNIX를 지원하였다. 1983년에는 시스템 V를 배포하였다.

C.1.2. Berkeley Begins Development

초기 UNIX의 작은 크기, 모듈성, 깔끔한 설계는 여러 컴퓨터 과학 조직에서 UNIX가 쓰일 수 있도록 했다. 버클리 VAX UNIX 작업은 1978년에 최초로 이루어졌다. 초기의 목적 중 하나는 TCP/IP를 지원하는 것이었다. 추가로, 버클리는 UNIX의 설계와 구현을 개선시키기 위해 동시대 운영 체제에서 많은 특성을 따왔다. 버클리 UNIX는 버클리 소프트웨어 배포판(BSD)으로 배포되었다. 1986년에는 4.3 BSD가 배포되었다. 다음 버전은 1988년에 배포된 4.3 BSD Tahoe였다. 최후 버전은 1993년에 배포된 4.4 BSD였다.

C.1.3. The Spread of UNIX

4 BSD는 아직도 많은 연구와 네트워킹 설치판에서 최고의 선택이다. UNIX의 컴퓨터 벤더에서의 넓은 인기는 UNIX를 가장 포터블한 운영 체제로 만들었고 사용자들이 UNIX가 특정한 컴퓨터 제조사에 상관없는 환경으로 인식되도록 하였다. 이후에 여러 표준화 프로젝트들이 진행되었다. 이에 따라 UNIX의 특징들은 단일 인터페이스로 수렴하였고 이는 인기를 더 드높였다. 1989년에는 System V 릴리즈 4가 배포되었다. UNIX는 크게 성공적이었다.

C.1.4. History of FreeBSD

이 장에서 다루는 UNIX 버전은 FreeBSD의 Intel 버전이다. 이는 1994~2000년까지 배포되었다. FreeBSD의 목적은 범용 소프트웨어 지원이었다.

C.2. Design Principles

UNIX는 시간 공유 시스템으로 설계되었다. 디스크 파일과 입출력 기기도 파일 시스템과 비슷하게 다뤄진다. UNIX는 복수 프로세스를 지원한다. UNIX는 이해하기 쉬울 만큼 작다. 또한 유연성을 갖고 있다. UNIX 시스템은 프로그래머를 위해 프로그래머에 의해 설계되었다. 이는 거의 C로 쓰여졌다. UNIX 설계 시스템은 초기부터 오픈 소스였다. UNIX는 패닉이라는 제어된 크래시를 수행하였다. 이런 초기 강점은 인기의 많은 부분을 일으켜주었다.

C.3. Programmer Interface

UNIX는 커널과 시스템 프로그램의 두 부분으로 구성되어 있다. 시스템 호출은 프로그래머 인터페이스를 정의한다. 대부분 시스템 프로그램은 C로 쓰여 있다. UNIX의 시스템 호출은 파일 조작, 프로세스 제어, 정보 조작의 세 부분으로 구성되어 있다.

C.3.1. File Manipulation

UNIX의 파일은 바이트의 나열이다. 파일은 트리 구조 디렉토리로 구성되어 있다. UNIX 파일 시스템은 절대 경로명과 상대 경로명을 갖고 있다. 파일은 디렉토리에서 여러 가지 이름으로 인식될 수 있다. 파일명 “.”은 디렉토리 자신에 대한 하드 링크이다. 하드웨어 기기도 파일 시스템 내 이름을 갖고 있다. 루트는 “/”이다. 사용자의 파일은 /usr 안에 각각 분리되어 저장된다. 각 디렉토리들은 더 구조화될 수 있다. 기본적 파일 조작을 하는 여러 시스템 호출이 있다. 파일 수식자는 이 프로세스가 연 파일에 대한 작은 테이블에 대한 인덱스이다. 각 read()나 write()는 파일의 현재 오프셋을 업데이트한다. 파일에 대한 정보는 stat() 시스템 호출로 알 수 있다. 디렉토리는 mkdir()로 생성된다. 파일 호출을 디렉토리에도 할 수 있지만 적합하진 않다.

C.3.2. Process Control

프로세스는 실행 중인 프로그램이다. 대개 execve() 시스템 호출을 사용해 프로세스의 가상 주소 공간을 새 프로그램의 것으로 교체한다. 프로세스는 exit() 시스템 호출로 종료될 수 있다. 프로세스간 가장 간단한 통신 형태는 파이프이다. 모든 사용자 프로세스는 init이라는 원본 프로세스의 후손이다. 사용자 식별자는 시스템 호출 – 특히 파일 접근에 대한 – 에 대한 사용자의 권한을 커널이 판단하기 위해 사용된다. 커널에게는 유효 사용자 식별자와 실제 사용자 식별자 2개가 사용된다.

C.3.3. Signals

시그널은 소프트웨어 인터럽트와 비슷한 예외 조건을 다루기 위한 기능이다. interrupt 시그널, SIGINT는 명령이 끝나기 전 명령을 멈추기 위해 쓰인다. 대부분의 시그널을 무시하거나 사용자 프로세스에 대한 루틴을 호출하기 위해 재배열이 이루어질 수 있다. 시그널은 유실될 수 있다. 시그널은 본래 예외 이벤트를 다루기 위해 만들어졌다. 오래된 시그널 구현에는 경합 조건이 내재하고 있었으나 이후에는 수정되었다.

C.3.4. Process Groups

연관된 프로세스의 그룹은 자주 협업하여 공통된 작업을 수행할 수 있다. 프로세스 그룹은 C 쉘에 사용되어 복수 작업의 수행을 제어할 수 있다.

C.3.5. Information Manipulation

구간 타이머와 현재 시간을 세팅하고 반환하는 시스템 호출이 존재한다.

C.3.6. Library Routines

UNIX의 시스템 호출 인터페이스는 라이브러리 루틴과 헤더 파일에 의해 지원되고 증강된다. 예를 들어 UNIX 입출력 시스템 호출은 바이트 블록의 읽기/쓰기를 지원한다. 수학적 함수, 네트워크 접근, 데이터 변환 등을 위한 추가 라이브러리 지원이 제공된다.

C.4. User Interface

UNIX 시스템의 프로그래머와 사용자는 쓰여지고 실행될 수 있는 시스템 프로그램을 다룬다. 공통된 시스템 프로그램은 여러 카테고리로 그룹화될 수 있다. ls 프로그램은 현재 디렉토리의파일명을 나열한다. 터미널에 파일을 표시하려면 사용자는 cat을 쓸 수 있다. 이 외에도 에디터, 컴파일러, 텍스트 포매터 등이 존재한다.

C.4.1. Shells and Commands

사용자에 의해 쓰여진 프로그램과 시스템 프로그램은 커맨드 인터프리터에 의해 대개 실행된다. 공용 쉘들은 커맨드 언어 문법을 다수 공유한다. 일부 명령어는 쉘에 내장되어 있기는 하지만 특정 명령어는 실행 가능한 바이너리 오브젝트 파일이다. 명령어의 실행은 fork() 시스템 호출 후 execve() 오브젝트 파일로 이루어진다. FreeBSD 시스템의 C 쉘은 작업 제어 기능을 갖고 있다.

C.4.2. Standard I/O

대부분의 프로세스는 파일을 열 때 3개의 수식자를 예상한다. 공용 쉘들은 어떤 파일이 프로세스의 표준 입출력 스트림에 열렸을 때 그 내용을 변경하기 위한 간단한 문법을 갖고 있다.

C.4.3. Pipelines, Filters, and Shell Scripts

파이프는 한 프로세스에서 다른 프로세스로 데이터를 가져올 때 쓰인다. pr 같은 명령어는 그 표준 입력을 표준 출력으로 필터링해서 전달한다. 범용 UNIX 쉘은 모두 프로그래밍 언어로서, 쉘 변수와 사용자 고수준 프로그래밍 제어 구성을 갖고 있다. 이 외부 사용자 관점은 UNIX의 정의로 볼 수 있으나 이는 쉽게 바뀌는 정의이다.

C.5. Process Management

운영 체제의 주요 설계 문제는 프로세스의 표현이다.

C.5.1. Process Control Blocks

프로세스와 연관된 가장 기본적 자료 구조는 프로세스 구조이다. 사용자 프로세스의 가상 주소 공간은 텍스트, 데이터, 스택 세그먼트로 나뉜다. 공유 가능한 텍스트가 있는 모든 프로세스는 그 프로세스 구조로부터 텍스트 구조로의 포인터를 갖고 있다. 페이지 테이블은 프로세스의 가상 주소로부터 물리적 주소로의 매핑에 대한 정보를 기록한다. 프로세스에 대한 정보는 프로세스가 프로세스 구조가 아닌 사용자 구조 내에 존재할 때 필요하다. 모든 프로세스는 사용자 모드와 시스템 모드가 있다. 예를 보자. fork() 시스템 호출은 자식 프로세스에 대해 새 프로세스 구조를 할당하고 사용자 구조를 복제한다. vfork() 시스템 호출은 데이터와 스택을 새 프로세스로 복제하지 않으며, 기존 프로세스의 페이지 테이블을 공유한다. 부모 프로세스가 크면 vfork()는 시스템 CPU 시간을 크게 아낀다. execve() 시스템 호출은 새 프로세스나 사용자 구조를 만들지 않는다.

C.5.2. CPU Scheduling

UNIX의 CPU 스케쥴링은 상호 작용하는 프로세스를 이용하기 위해 설계되었다. 모든 프로세스는 연관된 스케쥴링 우선도를 갖고 있다. 프로세스가 더 많은 CPU 시간을 누적할 수록 우선도는 더 낮아지고 반대도 같다. 오래된 UNIX 시스템은 순차 순환 스케쥴링에 대한 1초 퀀텀을 갖고 있었다. 커널에서 프로세스가 다른 프로세스에 의해 선점되지는 않는다. 예를 들어, 디스크 입출력의 완료는 기다리는 프로세스는 전송되는 데이터에 대응하는 버퍼 헤더의 주소에서 수면한다. 실제로 동작하는 프로세스는 스케쥴러에 의해 선택된다. 시그널이 호출되었을 때, 영향받는 다음 프로세스의 절반이 동작하기 전까지는 지연된다. 이벤트와 연관된 메모리는 없다. 이벤트 메커니즘에는 경합 조건이 존재한다. 텍스트 에디터와 같은 많은 프로세스는 입출력 바운드이며 일반적으로 입출력 대기에 기반해 스케쥴링된다. 여기서 CPU 스케쥴링이라고 이야기된 것은 단기 스케쥴링이다.

C.6. Memory Management

UNIX의 초기 개발은 다수가 PDP-11에서 수행되었다. 버클리는 페이징을 UNIX에 3BSD와 함께 도입하였다. 몇 가지 최적화가 있었다. 페이지 대체 알고리즘은 더 흥미롭다. BSD Tahoe는 참조 비트를 구현하는 시스템을 지원했다. 프로세스의 올바른 데이터 페이지가 너무 적지 않도록 하고 페이징 디바이스가 요청으로 흘러넘치지 않도록 하는 체크도 존재한다. 최소 최근 사용 시계 바늘 기법은 pagedaemon에 구현되어 있다. pagedaemon 프로세스가 깨어날 때마다 흐르는 시계 바늘의 수는 lotsfree에 도달하기 위한 프레임 수와 스케쥴러가 여러 이유로 판단한 프레임 수에 모두 의존한다. 스케쥴러가 페이징 시스템이 과부하되었다고 판단하면 프로세스는 과부하가 해소될 때까지 교환된다. 매개변수 lotsfree는 시계 바늘이 쓸고 지나가는 메모리의 1/4이며 desfree나 minsfree는 이와 똑같지만 가용 메모리의 일부로 제한되어 있다. 모든 프로세스의 텍스트 세그먼트는 공유이며 읽기 전용이다. CPU 스케쥴링, 메모리 교환, 페이징은 상호 작용한다.

C.7. File System

파일 시스템을 알아보자.

C.7.1. Blocks and Fragments

파일 시스템의 대다수는 데이터 블록으로 구성된다. 하드웨어 디스크 섹터는 대개 512 바이트이다. 블록과 조각 크기는 파일 시스템 생성 시에 파일 시스템의 의도된 사용처대로 세팅된다. 조각 재복사를 막기 위해 프로그램에 대해서는 공급이 주어져서 파일에 대한 블록 크기를 발견할 수 있도록 해서 그 크기의 전송이 이루어질 수 있도록 한다.

C.7.2. Inodes

파일은 inode로 표현되며 이는 디스크의 특정 파일에 대한 정보를 대다수 기록하고 저장한다. 아이노드는 파일의 사용자와 그룹 식별자, 파일의 최근 수정/접근 시간, 하드 링크의 수, 파일의 유형을 포함한다. 아이노드의 다음 3개의 포인터는 간접 블록이다. 파일 시스템의 최소 블록 크기는 4KB로, 2^32 바이트의 파일까지는 2개까지만의 간접 지시를 사용한다.

C.7.3. Directories

파일은 이 구현 단계에서는 디렉토리와 구별되지 않는다. FreeBSD에서 파일 이름은 가변 길이로, 255바이트까지를 차지하며 디렉토리도 이와 같다. 사용자는 파일명으로 파일을 참조하고 파일은 그 파일의 정의를 위해 아이노드를 쓴다. 처음에는 시작 디렉토리가 판정된다. 경로 마지막의 / 다음 이름은 파일명이다. 하드 링크는 다른 디렉토리 엔트리와 같다. 디스크가 아닌 파일은 디스크에 할당된 데이터 블록이 없다. 아이노드가 발견되면 open() 시스템 호출은 아이노드를 가리키는 파일 구조를 할당한다.

C.7.4. Mapping a File Descriptor to an Inode

열린 파일을 참조하는 시스템 호출은 파일 수식자를 매개변수로 전달해 파일을 가리킨다. read()와 write() 시스템 호출은 파일 내 위치를 매개변수로 받지 않는다. 파일 구조가 가리키는 아이노드 구조는 디스크 내 아이노드의 복제이다.

C.7.5. Disk Structures

사용자가 보는 파일 시스템은 대형 저장소의 데이터 – 대개 디스크로 지원된다. 물리적 기기를 복수의 파일 시스템으로 분할하는 것은 여러 이점이 있다. 드라이브의 파일 시스템의 수는 디스크의 크기와 컴퓨터 시스템의 목적에 따라 달라진다. 아이노드 구조의 비트는 아이노드가 파일 시스템을 마운트하고 있는지를 판단한다. 각 파일 시스템은 별개의 시스템 자원이며 파일의 집합을 표현한다.

C.7.6. Implementations

파일 시스템의 사용자 인터페이스는 간단하고 잘 정의되어 있으며, 파일 시스템 자체의 구현을 사용자에 큰 영향 없이 변경할 수 있게 한다. 4.0BSD에서는 파일 시스템에서 쓰이는 블록의 크기는 512바이트에서 1024바이트로 늘어났다. 4.2BSD는 버클리 빠른 파일 시스템을 추가해서 속도가 증가하였고 여러 특성들을 추가하였다.

C.7.7. Layout and Allocation Policies

커널은 논리적 기기 번호, 아이노드 번호의 쌍을 이용해 파일을 식별한다. 버전 7 파일 시스템과 함께, 파일의 블록은 디스크 내에서 아이노드 배열의 끝에서부터 파일 시스템의 끝까지 어디든 될 수 있다. 또 하나의 난점은 파일 시스템의 신뢰성이 의심스럽다는 점이다. 4.2BSD 파일 시스템 구현은 버전 7과는 매우 다르다. 특히 공간 할당이 다르다. 모든 실린더 그룹의 수퍼블록은 동일하며, 수퍼블록은 디스크가 손상되었을 때 이 중 하나로부터 복구될 수 있다. 실린더 그룹에서의 헤더 정보는 그룹의 처음에서 항상 시작하진 않는다. 디렉토리 목록 명령어 ls는 디렉토리 내 모든 파일의 아이노드를 읽어 이 모든 아이노드가 디스크 내 가까이 있도록 한다. 파일의 데이터 블록을 접근할 때의 디스크 헤드 탐색을 줄이기 위해, 같은 실린더 그룹의 블록을 가능한 자주 할당한다. 디스크 블록 할당 루틴에는 2단계까 있다. 빠른 파일 시스템의 늘어난 효율성으로 인해, 디스크는 원시 전송 용량으 30퍼센트가 활용된다. BSD Tahoe는 뚱뚱한 빠른 파일 시스템을 도입하여, 실린더 그룹당 아이노드의 수, 실린더 그룹당 실린더의 수, 구분되는 회전 위치의 수가 파일 시스템이 생성될 때 세팅되도록 하였다.

C.8. I/O System

운영 체제의 목적은 특정 하드웨어 기기의 특성을 사용자로부터 숨기는 데 있다. FreeBSD의 입출력은 크게 세 가지가 있다. 블록 기기는 디스크와 테입을 포함한다. 문자 기기는 터미널과 라인 프린터를 포함하나 블록 버퍼 캐시를 쓰지 않는 거의 대부분을 포함한다. 블록 기기나 캐릭터 기기는 2개의 메인 기기 클래스이다. 디바이스 드라이버는 그 클래스의 배열에 기록된 진입 지점과 그것이 쓰는 공용 버퍼링 시스템에 대해서만 커널에 의해 연결된다.

C.8.1. Block Buffer Cache

블록 기기는 블록 버퍼 캐시를 사용한다. 블록이 기기로부터 읽힐 때 캐시가 탐색된다. 쓰기 시에 요청되는 블록이 버퍼 캐시에 있으면 새 데이터가 버퍼에 놓이고 버퍼 헤더가 마크되어 버퍼가 수정되었고 즉각적인 입출력이 필요하지 않음을 알린다. FreeBSD 내 가용가능한 버퍼 내 데이터의 수는 대개 최대 8KB이다. 버퍼 내 데이터의 수는 사용자 프로세스가 버퍼 내 이미 있는 데이터를 쓰기 시작함에 따라서 커질 수 있다. 마그네틱 테이프와 같은 기기들은 블록이 특정 순서로 쓰여졌을 것을 요구한다. 버퍼 캐시의 크기는 시스템에 큰 영향을 끼치는데, 그것이 충분히 크면 캐시 히트의 퍼센트가 커질 수 있고 실제 입출력 전송의 수가 낮아지기 때문이다. 버퍼 캐시, 파일 시스템, 디스크 드라이버와 관련된 흥미로운 상호작용이 있다.

C.8.2. Raw Device Interfaces

거의 모든 블록 디바이스는 문자 인터페이스이며 이는 원시 디바이스 인터페이스라 불린다. 각 디스크 드라이버는 지연된 전송의 큐를 유지한다. 메인 메모리의 조각을 대응하는 사용자 프로세스의 가상 주소 공간으로 매핑하는 것은 간단하다. 커널은 교환과 페이징을 위한 전송을 적절한 기기에 대한 적절한 요청을 큐에 넣는 방식으로 처리한다. 4.2BSD 파일 시스템의 구현은 코드가 커널 내부로 이동하기 전 원시 디스크 인터페이스로 사용되는 사용자 프로세스로 쓰여지고 테스트되었다.

C.8.3. C-Lists

터미널과 터미널류 기기는 문자 버퍼링 시스템을 갖고 있어 문자의 작은 블록을 C-목록이라 불리는 연결 리스트로 들고 있다. 이런 목록들에서 문자들을 추가하거나 삭제하는 루틴들이 존재한다. 입력은 인터럽트 기반이다. 디바이스 기기는 자연적 큐를 무시하고 원시 큐로부터 문자들을 직접 반환할 수 있다.

C.9. Interprocess Communication

대다수 작업이 분리된 프로세스로 이뤄질 수 있지만, 많은 작업들은 프로세스간 통신을 필요로 한다.

C.9.1. Sockets

파이프는 UNIX의 고유한 프로세스간 통신 메커니즘이다. FreeBSD에서는 파이프는 소켓 메커니즘의 특수 케이스로 구현되어 있다. 소켓은 통신의 양 극단이다. FreeBSD에 구현된 도메인은 UNIX 도메인, 인터넷 도메인, XEROX 네트워크 서비스 도메인이다. 소켓 타입은 여러 가지가 있는데 스트림 소켓, 시퀀스 패킷 소켓, 데이터그램 소켓, 신뢰성 있게 전송되는 메시지 소켓, 원시 소켓 등이 있다. 호출에 의해 반환되는 정수값은 소켓 수식자이다. 다른 프로세스가 소켓을 주소화하기 위해서 소켓에는 이름이 필요하다. 소켓 프로세스간 통신을 사용해 통신하는 프로세스는 클라이언트-서버 모델을 따른다. 서버 프로세스는 socket()을 사용해 소켓을 만들고 bind()를 통해 서비스의 주소를 소켓에 연결한다. 소켓 유형에 대한 연결이 생성되면 양 끝점의 주소가 알려지며 데이터를 전송하기 위해서 추가 정보는 필요치 않다. 연결을 끊고 연관된 소켓을 파괴하기 위한 가장 간단한 방법은 소켓 수식자에 대한 close() 시스템 호출이다. 데이터그램 소켓 같은 어떤 소켓은 연결을 지원하지 않는다. select() 시스템 호출을 이용해 여러 파일 수식자/소켓 수식자에 대한 데이터 동시 전송을 할 수 있다.

C.9.2. Network Support

거의 모든 현재 UNIX 시스템은 UUCP 네트워크 기능을 지원하는데 이는 UUCP 메일 네트워크와 USENET 뉴스 네트워크를 지원하는 전화선에서 거의 사용된다. FreeBSD는 DARPA 인터넷 프로토콜인 UDP, TCP, IP, ICMP를 넓은 범위의 이더넷, 토큰-링, ARPANET 인터페이스를 통해 지원한다. ISO OSI 네트워킹 참조 모델은 네트워크 프로토콜의 7개 층과 이들간 통신의 강한 방식을 규정한다. FreeBSD 네트워크 구현과 그 소켓 기능으로의 확장판은 ARPANET 참조 모델 지향이다. ISO 모델은 한 층당 한 프로토콜로 통신한다는 제약이 있지만, ARM은 단일 층에서 여러 프로토콜을 허용한다. FreeBSD의 네트워킹 프레임워크는 ISO 모델이나 ARM보다 일반화되었다고 할 수 있다. 사용자 프로세스는 네트워크 프로토콜과 소켓 기능으로 통신한다. 소켓은 프로토콜에 의해 지원되며 이는 다른 프로토콜에 층층이 쌓일 수 있다. 프로토콜은 네트워크 하드웨어에 걸맞는 네트워크 인터페이스나 다른 프로토콜과 통신할 수 있다. 거의 자주, 네트워크 컨트롤러 타입마다 네트워크-인터페이스 드라이버가 존재한다. 네트워크 인터페이스의 기능은 네트워크가 필요로 하는 네트워크 하드웨어에 크게 의존한다. 소켓 기능과 네트워킹 프레임워크는 공통된 메모리 버퍼의 집합을 사용한다. 데이터는 일반적으로 레이어-소켓-프로토콜간 전달되며, 프로토콜-프로토콜, 프로토콜-네트워크 인터페이스로 전다된다.

C.10. Summary

UNIX의 초기 장점은 고수준 언어로 쓰여 있고, 소스 형태로 배포되어 있고, 강력한 운영 체제 원시 기능을 값싼 플랫폼으로 제공했다는 데에 있다. 이 장점들은 UNIX의 인기를 교육적, 연구적, 정부 기관적 그리고 상업적 세계로 확대시켰다. 이 인기는 UNIX에 많은 압박을 주어 여러 개선된 기능을 추가시켰다. UNIX는 트리 구조 디렉토리로 된 파일 시스템을 제공한다. 커널은 파일을 비구조화된 바이트의 서열로 지원한다. 직접 접근과 순차적 접근은 시스템 호출과 라이브러리 루틴을 통해 지원된다. 파일은 고정 크기 데이터 블록으로 저장되어 있으며 이를 따라오는 조각이 있을 수 있다. 데이터 블록은 아이노드 내 포인터로 발견된다. 디렉토리 엔트리는 아이노드를 가리킨다. 디스크 공간은 실린더 그룹으로부터 할당되어 헤드 이동을 최소화하고 성능을 개선한다. UNIX는 멀티프로그래밍 시스템이다. 프로세스는 다른 프로세스를 fork() 시스템 호출로 쉽게 만들 수 있다. 프로세스는 파이프나, 더 일반적으론 소켓으로 통신한다. 이들은 시그널에 의해 제어되는 작업들로 그룹화될 수 있다. 프로세스는 두 구조로 표현된다. 프로세스 구조와 사용자 구조. CPU 스케쥴링은 동적으로 계산되는 우선도 알고리즘을 사용하며 이는 극단적 경우로는 순차 순환 스케쥴링으로 환원된다. FreeBSD 메모리 관리는 페이징에 의해 지원되는 교환을 사용한다. pagedaemon 프로세스는 수정된 이차 기회 페이지 대체 알고리즘을 사용해 자유 프레임을 유지해 존재하는 프로세스를 지원한다. 페이지와 파일 입출력은 블록 버퍼 캐시를 사용해 실제 입출력의 수를 최소화한다. 터미널 기기는 별개의 캐릭터 버퍼링 시스템을 사용한다. 네트워킹 지원은 FreeBSD의 가장 중요한 특성 중 하나이다. 소켓 개념은 다른 프로세스에 접근하기 위한 프로그래밍 메커니즘을 제공하며 이는 네트워크를 가로지르기도 한다. 소켓은 여러 프로토콜 집합에 대한 인터페이스를 제공한다.