본문 바로가기

개발기술/운영체제 핵심개념

C언어 정리

C언어 학습의 필요성

  • 리눅스 커널은 C로 작성되어 있습니다. 따라서 커널의 구조와 동작 방식을 이해하려면 C 언어에 대한 지식이 필요합니다.
  • 추상화 언어의 최적화 가능
    • I/O 성능과 버퍼링 이해 가능: C를 통해 버퍼, 블로킹/논블로킹 I/O, 파일 디스크립터, select/poll 등 성능과 밀접한 개념 이해
    • 메모리, 포인터, 시스템 콜, 버퍼링, 프로세스/스레드 같은 개념을 C로 직접 경험하면,
      • JVM·GC 내부 동작
      • 네트워크 I/O 병목
      • 대용량 데이터 처리 최적화
      • 성능 튜닝
        이런 영역에서 문제를 더 깊이 이해하고 해결할 수 있는 기반이 생깁니다.

 

포인터란?

포인터(pointer)는 메모리 주소를 저장하는 변수입니다. 

 

포인터기호

  • & : 주소 연산자, ~의 주소를 구해라.
  • * :  역참조 연산자, 그 주소에 있는 값을 가져와라.
  •  int * p : "p는 int를 가리키는 주소(포인터)이다" 라는 선언
    • 주소는 "포인터 타입"이라고하는 별도의 타입을 보유하고 있다. 주소는 숫자처럼 생겼지만, 숫자처럼 쓰면 안 되는 특별한 "종류의 값임
  • 역참조 연산자는 변수의 값을 바꿀때 주로 사용됨
int x = 10;
int *p = &x;   // 선언 → p는 int를 가리키는 포인터

printf("%p\n", p);    // p: 주소 자체
printf("%d\n", *p);   // *p: 주소에 있는 값 (즉, x)

 

C에서는 함수 인자 전달 방식이 "값 복사(pass by value)"

int a = 10;
change(a);
printf("%d\n", a);  // 👉 여전히 10! 안 바뀜
int a = 10;
change(&a);          // a의 주소를 전달
printf("%d\n", a);   // 👉 100! 값이 실제로 바뀜

 

Java에서도 함수 인자 전달 방식이 "값 복사(pass by value)"

public static void main(String[] args) {
    int a = 10;
    change(a);
    System.out.println(a); // ➤ 10 (안 바뀜)
}
public static void main(String[] args) {
    Box box = new Box();
    box.value = 10;

    change(box);
    System.out.println(box.value);  // ➤ 100 (바뀜!)
}

 

 

자료타입

int fd[2];  : 정수형 2개를 담을 수 있는 배열 변수 fd를 선언한다.

 

 

포인터를 활용한 변수변환 함수

pipe(int fd[2]);는 어떻게 출력(return)의 의미가 되는가?

  C 언어는 하나의 값만 return할 수 있기 때문에, 여러 값을 반환할 필요가 있을 때는 "포인터(주소)"를 인자로 받아서 그 안에 값을 담아주는 방식을 씁니다.

 

 

 

 

 

 

구조체(struct)란

 

서로 다른 타입의 데이터들을 하나로 묶어서 "하나의 새로운 데이터 타입"으로 정의하는 것.

  • Person 이라는 새로운 데이터 타입을 만들었고, name, age, height 라는 서로 다른 타입을 묶어 하나로 보관.
  • 보통 메서드 없 속성만 가짐
struct epoll_event {
    uint32_t     events; /* EPOLLIN, EPOLLOUT 같은 이벤트 플래그 */
    epoll_data_t data;   /* 유저가 지정할 데이터, 보통 fd */
    };

 

 

Union이란

 

여러 멤버(필드)를 같은 메모리 공간에 겹쳐서 저장하는 C/C++ 의 데이터 타입 

 

  • struct 는 멤버들이 메모리를 각각 따로 차지하지만,
  • union 은 모든 멤버가 같은 메모리 위치를 공유.
union Example {
int x;
float y;
};

typedef union 은? : typedef 를 붙여서 별명(타입 이름)을 만들어주는 것.

 

typedef union epoll_data {
    void *ptr;
    int fd;
    uint32_t u32;
    uint64_t u64;
    } epoll_data_t;

Example_t 로 타입을 선언할 수 있으며 데이터 구조 내에 아  중 하나로 쓸 수 있게 함.

 

  • pointer
  • file descriptor
  • 32bit 정수
  • 64bit 정수

 

 

 

 

✅ 백엔드 개발자가 알아야 할 주요 시스템콜 목록

📁 1. 파일 및 입출력 관련

시스템콜설명
open() 파일 열기 → FD 반환
read() FD로부터 바이트 단위 데이터 읽기
write() FD에 바이트 단위 데이터 쓰기
close() 열린 파일 디스크립터 닫기
lseek() 파일 커서 위치 이동
fsync() 버퍼링된 데이터를 디스크에 강제 저장
fstat() 파일 정보 조회 (크기, 권한 등)
dup(), dup2() FD 복제 (리다이렉션에 필수)
pipe() 부모-자식 간 단방향 통신 (쉘의 `
unlink() 파일 삭제 (디스크 공간 회수는 refcount=0일 때)
 

 


🌐 2. 네트워크 관련 (소켓 기반)

시스템콜설명
socket() 소켓 생성 (FD 반환)
bind() 소켓에 IP/PORT 할당
listen() 수신 대기 설정 (서버용)
accept() 클라이언트 연결 수락 (새 FD 생성)
connect() 클라이언트에서 서버 연결 시도
send() / recv() TCP 소켓에서 데이터 송수신
read() / write() 소켓 FD에도 사용 가능 (send/recv와 유사)
shutdown() 소켓 연결의 특정 방향 종료
close() 소켓 FD 닫기
 

🧵 3. 프로세스 및 스레드

시스템콜설명
fork() 프로세스 복제 (자식 프로세스 생성)
exec() 계열 다른 프로그램으로 현재 프로세스 덮어쓰기
wait() / waitpid() 자식 프로세스 종료 대기
exit() 현재 프로세스 종료
getpid() / getppid() 현재 / 부모 프로세스 ID 조회
clone() 리눅스 스레드 생성 (pthread 기반)
 

🧠 4. 메모리/자원 관련

시스템콜설명
brk() / sbrk() 힙 메모리 영역 조절 (구형 방식)
mmap() / munmap() 파일/메모리를 프로세스 주소 공간에 매핑
mprotect() 메모리 접근 권한 변경
mlock() / munlock() 메모리를 스왑 불가능하게 고정
getrlimit() / setrlimit() FD 수 제한 등 자원 제한 설정
 

🕳️ 5. 기타 (디버깅, 성능, 제어)

시스템콜설명
select() / poll() / epoll_wait() 여러 FD 동시 감시 (비동기 I/O 이벤트)
nanosleep() 고해상도 시간 지연
time() / gettimeofday() 현재 시간 조회
ioctl() 장치나 파일에 특수 명령 전달
kill() 프로세스에 시그널 전송
getcwd() / chdir() 현재 작업 디렉토리 조회/변경
 

✅ 실무에서 특히 중요한 핵심 Top 10

카테고리시스템콜
파일 I/O open, read, write, fsync
FD 조작 dup2, pipe, close
네트워크 socket, bind, accept, connect
비동기 select, epoll_wait
프로세스 fork, exec, wait

 

 

'개발기술 > 운영체제 핵심개념' 카테고리의 다른 글

POSIX multiplexing  (3) 2025.07.08
POSIX I/O와 스트림  (0) 2025.05.16
운영체제의 표준화 : POSIX와 시스템 콜  (0) 2025.05.16
Blocking / Non-Blocking I/O  (0) 2025.02.15