프로세스 =
메모리 공간을 차지한 상태에서 실행중인 프로그램
프로세스는 프로세스간에 코드영역, 데이터 영역, 힙 영역, 스택 영역을 공유하지 않고 각자 가지고 있음
코드영역: 프로그램의 실제 코드가 저장되어 있는 영역
스택영역 : 로컬변수, 함수에 호출에 관련된 정보, 임시데이터가 저장되는 영역
힙영역 : 동적 메모리 할당에 사용되는 영역
데이터영역 : 전역변수등의 데이터가 저장되는 영역
프로세스(자세히) =
OS는 가상메모리를 이용하여 프로그램을 관리
%참고
c언어 상에서 사용하는 메모리는 가상메모리(register + cach + 램 + 하드디스크)
다중접속 서버의 구현방법들
멀티프로세스 기반 서버 = 다수의 프로세스를 생성하는 방식으로 서비스 제공
멀티플렉싱 기반 서버 = 입출력 대상을 묶어서 관리하는 방식으로 서비스 제공
멀티쓰레딩 기반 서버 = 클라이언트의 수만큼 쓰레드를 생성하는 방식으로 서비스 제공
프로세스 ID = 모든 프로세스는 생성되는 행테에 상관없이 운영체제로부터 ID를 부여 받음
호출한 프로세스의 복사본을 생성(메모리 영역까지 동일하게 복사)
#include <unistd.h>
pid_t fork(void);
성공시 프로세스 id, 실패시 -1반환
부모 프로세스
fork함수의 반환 값은 자식 프로세스의 id
자식 프로세스
fork함수의 반환 값은 0
좀비 프로세스
생성 이유 :
자식 프로세스는 실행이 끝나고 반환 값을 운영체제에 전달됨
운영체제는 이 값이 자식 프로세스를 생성한 부모 프로세스에게 전달될 때까지 자식 프로세스를 소멸시키지 않음(=좀비 프로세스)
부모프로세스는 운영체제에게 반환 값을 달라는 함수를 호출하면 반환 값이 부모프로세스에게 전달되고 자식 프로세스는 소멸
좀비 프로세스의 소멸1
#include <sys/wait.h>
pid_t wait(int* statloc);
성공시 종료된 자식 프로세스의 ID, 실패시 -1 반환
종료된 자식 프로세스가 없다면, 임의의 자식 프로세스가 종료될 때까지 블로킹 상태에 놓임
WIFEXITED(status) 자식 프로세스가 정상 종료한 경우 참(true)을 반환
WEXITSTATUS(status) 자식 프로세스의 전달 값을 반환
좀비 프로세스의 소멸2
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int* statloc, int options);
성공시 종료된 자식 프로세스의 ID(or 0), 실패시 -1 반환
pid : 종료를 확인하고자 하는 자식 프로세스의 ID 전달, 이를 대신해서 -1을 전달하면 wait 함수와 마찬가지로 임의의 자식 프로세스가 종료되기를 기다림
statloc : wait함수의 매개변수 statloc과 동일한 의미로 사용
options 헤더파일 sys/wait.h에 선언된 상수 WNOHANG을 인자로 전달하면, 종료된 자식 프로세스가 존재하지 않아도 블로킹 상테에 있지않고, 0을 반한하면서 함수를 빠져 나옴
시그널함수
#include <signal.h>
void (*signal(int signo, void (*func)(int)))(int);
// = void (*) (int) signal(int signo, void (*func)(int))
------------ --------------------------------
반환값 함수이름(매개변수)
시그널 발생시 호출되도록 이전에 등록된 함수의 포인터 반환
반환 형 : void(*)(int) <= 함수포인터
함수이름 : signal
매개변수 선언 : int signo, void(*func)(int)
반환형 : 매개변수형이 int이고 반환형이 void인 함수 포인터
signal 함수를 통해서 등록 가능한 특정 상황과 그 상황에 할당된 상수
SIGALRM : alarm 함수호출을 통해서 등록된 시간이 된 상황
SIGINT : ctrl+c가 입력된 상황
SIGCHLD : 자식 프로세스가 종료된 상황
alarm 함수
unsigned int alarm(unsigned int seconds);
0 또는 sigalrm시그널이 발생하기까지 남아있는 시간을 초 단위로 반환
sigaction 함수
int sigaction(int signo, const struct sigaction* act, struct sigaction* oldact);
성공시 0, 실패시 -1 반환
signo : signal 함수와 마찬가지로 시그널의 정보를 인자로 전달
act : 첫 번째 인자로 전달된 상수에 해당하는 시그널 발생시 호출될 함수(시그널 핸들러)의 정보 전달
oldact : 이전에 등록되었던 시그널 핸들러의 함수 포인터를 얻는데 사용되는 인자, 필요 없다면 0 전달
struct sigaction
{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
}
시그널함수 설명
만약 다음과 같은 함수가 있다고 합시다...
void func(int a);
이러면 함수이름은 func 이고 패러미터는 int a 이고 리턴은 void 이지요
그러면 이 함수를 가리키는 포인터는 어떻게 쓸까요?
void (*p)(int a);
이렇게 씁니다. 즉, 포인터 p 가 함수를 가리키는 것이고 그 함수의 패러미터가 int a 인것이지요
이때 함수포인터가 지시하는 함수의 패러미터는 이름을 생략해도 됩니다.
물론 함수 선언할 때 생략해도 되기 때문에 이것이 허용되는 것이지요...
고로...
void (*p)(int);
이렇게만 해도 됩니다.
님께서 헷갈리시는 것이 바로 이름도 없이 int만 (int)로 나오니까 혼동하신 듯 하시네요
또 signal 함수의 프로토타입 설명을 요구하셔서 아래에 적어 보았습니다.
void (*signal(int signum, void (*handler)(int)))(int);
위의 함수 프로토타입을 이해해 봅시다
그러기 위하여 위의 함수를 분해해 보겠습니다.
먼저 signal이라는 이름부터 봅시다.
signal은 바로뒤의 괄호로 보아 함수이름이 됩니다.
(위의 문장에서 적색 부분)
즉, signal( ) 이 기본적인 모양이지요...
함수는 어떤것들을 지정합니까?
함수가 받는 parameter와 리턴 타입을 지정해 줘야 합니다.
당연히 parameter는 괄호안에 적지요...
그럼 이 함수의 parameter는 뭘까요?
parameter까지 적어봅시다. (보라색 부분)
signal(int signum, void (*handler)(int))
분석해 보면 이 함수는 parameter가 두개인 것을 알수 있습니다.
signum과 handler 가 그것입니다.
signnum은 int 타입입니다.
그럼 handler는 타입이 뭘까요?
handler 관련 부분만 추려볼까요?
void (*handler)(int)
이렇게 됩니다. 이게 뭔가요? 함수포인터입니다.
즉, handler는 함수포인터로서 위에서 이름빼고 보면 void (*)(int) 가 됩니다.
즉, int를 받고 리턴이 void인 함수의 포인터입니다.
자, 그럼 signal 함수의 패러미터는 이해되셨는지요?
그럼 이번에는 signal 함수의 리턴을 볼까요?
void (*signal(int signum, void (*handler)(int)))(int);
여기서 ( ) 안의 것은 패러미터이니까 제외하고 보면
void (*signal(...))(int);
이렇게 됩니다. 자 그럼 이게 뭘까요?
위에서 빨간부분은 signal 함수이므로 이것을 빼고 보면 나머지가 바로
signal 함수의 리턴타입이 되는 겁니다.
즉, void (*)(int) 아니겠습니까?
이것이 signal 함수의 리턴입니다. 결국 하까 본 handler 함수와 동일한 모양이지요
int를 받고 리턴이 void인 함수의 포인터 입니다.
님께서 질문하신 (int)는 결국 signal 함수의 리턴인 함수포인터가 가리키는 함수의
패러미터 타입인 것입니다.
그럼 전체적인 해석이 되셨는지요?
void (*signal(int signum, void (*handler)(int)))(int);
위에서 보시면 적색은 signal 함수 표시이고
보라색은 이 함수의 패러미터를 보이고 있는것입니다. (signum과 handler)
그리고 파란색은 리턴 타입을 보이고 있습니다. void (*)(int)
추가로 말씀드리면 signal 함수의 두번째 패러미터인 handler 의 타입과
이 signal 함수의 리턴타입은 둘 다 void (*)(int)로 일치 합니다.