[OS] system call 함수
1. fork
- 프로세스를 생성하고자 할 때 사용하는 system 함수
- fork 함수를 호출하는 프로세스는 부모 프로세스가 되고, 새롭게 생성되는 프로세스는 자식 프로세스가 됨
- 자식 프로세스는 부모 프로세스의 메모리를 그대로 복하여 가지게 됨
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
pid_t pid;
int x;
x = 0;
pid = fork();
if(pid > 0) { // 부모 프로세스
x = 1;
printf("부모 PID : %ld, x : %d , pid : %d\n",(long)getpid(), x, pid);
}
else if(pid == 0){ // 자식 프로세스
x = 2;
printf("자식 PID : %ld, x : %d\n",(long)getpid(), x);
}
else { // fork 실패
printf("fork Fail! \n");
return -1;
}
return 0;
}
2. exec
- system command에 해당하는 명령어를 수행하는 함수
- 종류
#include <unistd.h>
// path를 실행하며, arg0 ~ argn을 인자로 전달
int execl(const char *path, const char *arg0, ... , const char *argn, (char *)0);
// path를 실행하며, argv 를 인자로 전달
int execv(const char *path, char *const argv[]);
// path를 실행하며, arg0 ~ argn을 인자로 전달 및 envp에 새로운 환경 변수 설정 가능
int execle(const char *path, const char *arg0, ... , const char *argn, (char *)0, char *const envp[]);
// file을 실행하며 arg0 ~ argn을 인자로 전달, 파일은 이 함수를 호출한 프로세스의 환경 변수 PATH에 정의된 경로를 찾음
int execve(const char *file, const char *arg0, ... , const char *argn, (char *)0);
// file을 실행하며 argv를 인자로 전달
int execvp(const char *file, char *const argv[]);
3. select
- 다중 입출력으로 프로그램에서 여러 개의 파일을 작업하고자 할 때 사용하는 함수
-
block/async 입출력 모델 중 하나
- 예를 들어 A, B, C, D 4개의 파일을 다루는 작업을 하고 싶다고 가정할 때
- A 파일 작업
- A 파일 작업 마침
- B 파일 작업
- B 파일 작업하다가 block 상태에 빠짐
- 예를 들어 read() 함수를 호출했는데 읽을 파일이 없다면 프로그램을 읽을 내용이 생길 때까지 block 됨
- 솔루션으로 파일을 순서대로 작업할 게 아니라 작업할 준비가 된 파일에 대해서만 작업을 하면 됨, 그것에 대한 시초가 select 시스템콜
#include <sys/select.h>
int select(int n,
fd_set* readfds,
fd_set* writefds,
fd_set* exceptfds,
struct timeval* timeout);
FD_CLR(int fd, fd_set* set);
FD_ISSET(int fd, fd_set* set);
FD_SET(int fd, fd_set* set);
FD_ZERO(fd_set* set);
- select는 Fd가 입출력을 수행할 준비가 되거나 timeout 변수에 정해진 시간이 경과할 때까지만 block이 됨
- readfds : 읽기가 가능한 지 감시
- writhefds : 쓰기가 가능한 지 감시
- exceptfds : 예외가 발생했거나 대역을 넘어선 소켓이 존재하는 지 감시
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define TIMEOUT 5
#define BUF_LEN 1024
int main() {
struct timeval tv;
fd_set readfds;
int ret;
// 표준 입력에서 입력을 기다리기 위한 준비
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
// select가 5초 동안 기다리도록 timeval 구조체를 설정
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;
// select() 시스템콜을 이용해 입력을 기다림.
ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
if (ret == -1) {
perror("select");
return 1;
}
else if (!ret){
printf("%d seconds elapsed.\n", TIMEOUT);
return 0;
}
// select() 시스템콜이 정수를 반환하면 block없이 즉시 읽기가 가능
if (FD_ISSET(STDIN_FILENO, &readfds)) {
char buf[BUF_LEN + 1];
int len;
// '블록(block)'없이 읽기가 가능
len = read(STDIN_FILENO, buf, BUF_LEN);
if (len == -1) return 1;
if (len) {
buf[len] = '\0';
printf("read: %s\n", buf);
}
return 0;
}
}
참고
개발여행기 wikipedia_fork bbolmin 팡투루야
This is personal diary for study documents.
Please comment if I'm wrong or missing something else 😄.
댓글남기기