nginx 학습 13 초기 fork 와 nginx 데 몬 ngxdaemon
자, nginx 의 데 몬 생 성 을 보고 fork 를 배우 고 있 습 니 다.
http://blog.csdn.net/xiaoliangsky/article/details/39998373
1nginx 데 몬
코드 직접 보기:
ngx_int_t ngx_daemon(ngx_log_t *log)
{
int fd;
switch (fork()) {// fork
case -1://fork -1
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
return NGX_ERROR;
case 0://
break;
default://
exit(0);//
}
ngx_pid = ngx_getpid();
if (setsid() == -1) {// ,
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
return NGX_ERROR;
}
umask(0);//
/* 、 /dev/null( )*/
fd = open("/dev/null", O_RDWR);
if (fd == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"open(\"/dev/null\") failed");
return NGX_ERROR;
}
if (dup2(fd, STDIN_FILENO) == -1) {// fd, /dev/null
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
return NGX_ERROR;
}
if (dup2(fd, STDOUT_FILENO) == -1) {// fd, /dev/null
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
return NGX_ERROR;
}
#if 0
if (dup2(fd, STDERR_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
return NGX_ERROR;
}
#endif
if (fd > STDERR_FILENO) {
if (close(fd) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
return NGX_ERROR;
}
}
return NGX_OK;
}
여 기 는 설명 이 많 지 않 고 아래 의 내용 을 보면 위의 코드 가 매우 간단 하 다 는 것 을 알 수 있다.2fork 함수
fork 에서 만 든 새 프로 세 스 를 하위 프로 세 스 (child process) 라 고 합 니 다.이 함 수 는 한 번 호출 되 었 으 나 두 번 되 돌 아 왔 다.두 번 의 반환 차 이 는 하위 프로 세 스 의 반환 값 이 0 이 고, 부모 프로 세 스 의 반환 값 은 새 프로 세 스 (하위 프로 세 스) 의 프로 세 스 id 입 니 다.하위 프로 세 스 id 를 부모 프로 세 스에 되 돌려 주 는 이 유 는 프로 세 스 의 하위 프로 세 스 가 하나 이상 일 수 있 기 때 문 입 니 다. 모든 하위 프로 세 스 의 프로 세 스 id 를 얻 을 수 있 는 함수 가 없습니다.하위 프로 세 스에 있어 서 fork 가 0 을 되 돌려 주 는 이 유 는 언제든지 getpid () 를 호출 하여 자신의 pid 를 가 져 올 수 있 기 때 문 입 니 다.부모 프로 세 스 의 id 를 가 져 오기 위해 getppid () 를 호출 할 수도 있 습 니 다.(프로 세 스 id 0 은 항상 교환 프로 세 스에 서 사용 되 기 때문에 하위 프로 세 스 id 가 0 일 수 없습니다.)fork 이후 운영 체 제 는 부모 프로 세 스 와 똑 같은 하위 프로 세 스 를 복사 합 니 다. 부자 관계 라 고 하지만 운영 체제 에서 볼 때 그들 은 형제 관계 와 같 습 니 다. 이 두 프로 세 스 는 코드 공간 을 공유 하지만 데이터 공간 은 서로 독립 되 어 있 습 니 다. 하위 프로 세 스 데이터 공간 에서 의 내용 은 부모 프로 세 스 의 완전한 복사 이 고 명령 포인터 도 똑 같 습 니 다.하위 프로 세 스 는 부모 프로 세 스 가 현재 실행 중인 위치 (두 프로 세 스 의 프로그램 카운터 pc 값 이 같 습 니 다. 즉, 하위 프로 세 스 는 fork 반환 에서 시작 합 니 다) 를 가지 고 있 지만, 한 가지 차이 가 있 습 니 다. fork 가 성공 하면 하위 프로 세 스 에서 fork 의 반환 값 은 0 입 니 다. 부모 프로 세 스 에서 fork 의 반환 값 은 하위 프로 세 스 의 프로 세 스 번호 입 니 다. fork 가 성공 하지 못 하면 부모 프로 세 스 는 오 류 를 되 돌려 줍 니 다.
열 을 열거 하 다.
int main()
{
int count;
int flag;
pid_t pid;
pid = fork();
if (pid > 0)
{
printf("parent process is run
");
flag = 1;
}
else if (pid < 0)
{
printf("fork is error
");
exit(-1);
}
else
{
printf("child is run
");
flag = 0;
}
count = 0;
if (flag)
{
printf("count in parent is : %d
", ++count);
}
else
{
printf("count in child is : %d
", ++count);
}
return 0;
}
운행 결 과 는 다음 과 같다.parent process is run
count in parent is : 1
child is run
count in child is : 1
이 예 에서 알 수 있다.1 부모 프로 세 스 와 하위 프로 세 스 가 같은 코드 를 실 행 했 습 니 다.
2. 부모 프로 세 스 와 하위 프로 세 스 는 데이터 공간 을 공유 하지 않 습 니 다. 그렇지 않 으 면 count 의 값 이 같 을 수 없습니다.
3fork 프로 세 스 가 두 번 되 돌 아 왔 고 부모 프로 세 스 가 돌아 올 때 pid 가 0 보다 크 며, 하위 프로 세 스 가 돌아 올 때 pid = 0 이 며, 하위 프로 세 스 는 돌아 올 때 부터 실 행 됩 니 다.
다음은 '고급 프로 그래 밍' 이 상세 하 게 소개 한 부자 프로 세 스 간 의 관계 다.
포크 에서 나 온 하위 프로 세 스 는 기본적으로 프로 세 스 번 호 를 제외 하고 부모 프로 세 스 의 모든 것 을 복사 합 니 다. 기본적으로 모든 것 이 아니 라 는 것 을 의미 합 니 다. 다음은 하위 프로 세 스 가 부모 프로 세 스에 서 무엇 을 물 려 받 았 는 지, 아무것도 물 려 받 지 않 았 다 는 것 을 말 합 니 다.하위 프로 세 스 는 부모 프로 세 스 자원 자체 가 아 닌 부모 프로 세 스 의 복사 만 받 을 수 있 음 을 주의해 야 합 니 다.하위 프로 세 스 에서 부모 프로 세 스 로 계승 하기: 1. 프로 세 스 의 자격 (real) / 유효 (effective) / 저 장 된 사용자 번호 (UID) 와 그룹 번호 (GID) 2. 환경 (environment) 3. 스 택 4. 메모리파일 설명자 설정 에 대해 POSIX. 1 은 모든 디 렉 터 리 흐름 이 exec 함수 호출 시 종료 되 어야 합 니 다. 더 자세 한 설명 은 'UNIX 환경 고급 프로 그래 밍' W. R. Stevens, 1993, 유 진원 등 역 (이하 '고급 프로 그래 밍'), 3.13 절 과 8.9 절 참조 7. 신호 (signal) 제어 설정 8. nice 값 설정(번역자 주: nice 값 은 nice 함수 로 설정 되 어 있 습 니 다. 이 값 은 프로 세 스 의 우선 순 위 를 표시 합 니 다. 수치 가 작 을 수록 우선 순위 가 높 습 니 다) 프로 세 스 스케줄 링 클래스 (scheduler class)(번역자 주: 프로 세 스 스케줄 링 카 테 고리 란 프로 세 스 가 시스템 에서 스케줄 링 될 때 속 하 는 카 테 고리 입 니 다. 카 테 고리 마다 우선 순위 가 다 릅 니 다. 프로 세 스 스케줄 링 카 테 고리 와 nice 값 에 따라 프로 세 스 스케줄 러 는 각 프로 세 스 의 전체 우선 순위 (Global process prority), 우선 순위 가 높 은 프로 세 스 를 계산 할 수 있 습 니 다. 8. 프로 세 스 그룹 번호 9. 대화 기 ID (Session ID) (번역자 주: 번역문 은'고급 프로 그래 밍' 이란 프로 세 스 가 속 한 대화 기 (session) ID 를 말 합 니 다. 하나의 대화 기 는 하나 이상 의 프로 세 스 그룹 을 포함 하고 '고급 프로 그래 밍' 9.5 절 참조) 10. 현재 작업 디 렉 터 리 11. 루트 디 렉 터 리 (번역자: 루트 디 렉 터 리 는 반드시 '/' 가 아니 라 chroot 함수 로 변경 할 수 있 습 니 다) 12. 파일 방식 으로 차단 자 (file mode creation mask (umask) 를 만 들 수 있 습 니 다.(번역자 주: 번역문 은 에서 추출 한 것 입 니 다. 새 파일 을 만 드 는 데 부족 한 차단 자 를 말 합 니 다) 13. 자원 제한 14. 터미널 하위 프로 세 스 만 의 고유: 프로 세 스 번호 1. 서로 다른 부모 프로 세 스 번호 (번역자 주: 즉, 하위 프로 세 스 의 부모 프로 세 스 번호 와 부모 프로 세 스 번호 가 다 르 고 부모 프로 세 스 번 호 는 getppid 함수 에서 얻 을 수 있 습 니 다) 2. 자신의 파일 설명자 와 디 렉 터 리 흐름 의 복사(번역자 주: 디 렉 터 리 흐름 은 opendir 함수 로 만 들 어 졌 습 니 다. 순서대로 읽 기 때문에 '디 렉 터 리 흐름' 이 라 고 부 릅 니 다) 3. 하위 프로 세 스 는 부모 프로 세 스 의 프로 세 스, 본문 (text), 데이터 와 다른 잠 금 메모리 (memory locks) 를 계승 하지 않 습 니 다.'The GNU C Library Reference Manual' 2.2 판, 1999, 3.4.2 절) 5. tms 구조 에서 시스템 시간 (번역자: tms 구 조 는 times 함수 에서 얻 을 수 있 습 니 다. 프로 세 스 를 기록 하기 위해 중앙 처리 장치 (CPU: Central Processing Unit) 를 사용 하 는 데 네 개의 데 이 터 를 저장 합 니 다.사용자 시간, 시스템 시간, 사용자 각 하위 프로 세 스 합계 시간, 시스템 각 하위 프로 세 스 합계 시간 포함) 6. 자원 사용 (resource utilizations) 을 0 8 로 설정 합 니 다. 차단 신호 집합 을 빈 집합 으로 초기 화 합 니 다.9. timer create 함수 로 만 든 타 이 머 를 계승 하지 않 음 10. 비동기 입력 과 출력 을 계승 하지 않 음
3 데 몬 생 성
데 몬배경 에서 실행 되 는 특수 한 프로 세 스 입 니 다. 터미널 을 제어 하 는 데 독립 되 어 있 으 며, 주기 적 으로 어떤 작업 을 수행 하거나 어떤 사건 을 처리 하 기 를 기다 리 고 있 습 니 다. 그 다음 데 몬 은 실행 전 환경 과 격 리 되 어야 합 니 다. 이 환경 은 닫 히 지 않 은 파일 설명자, 제어 터미널, 세 션 과 프로 세 스 그룹, 작업 디 렉 터 리, 파일 마스크 생 성 등 을 포함 합 니 다.항상 데 몬 은 부모 프로 세 스 (특히 셸) 에서 계승 합 니 다. 마지막 으로 데 몬 의 시작 방식 은 특별한 점 이 있 습 니 다. 리 눅 스 시스템 이 시 작 될 때 시작 스 크 립 트 / etc / rc. d 에서 시작 할 수 있 습 니 다. 작업 계획 프로 세 스 crond 에서 시작 할 수 있 고 사용자 터미널 (보통 셸) 에서 실행 할 수 있 습 니 다.
데 몬 생 성 절차:
1) 백그라운드 에서 실행
제어 단말 기 를 걸 지 않 기 위해 Daemon 을 백 엔 드 에 넣 고 실행 합 니 다. 방법 은 프로 세 스에 서 fork 를 호출 하여 부모 프로 세 스 를 종료 시 키 고, daemon 을 하위 프로 세 스에 서 백 엔 드 로 실행 시 키 는 것 입 니 다.
pid = fork();
if (pid > 0)
{
printf("parent is exit
");
exit(0);//
}
2) 제어 단말기 에서 벗 어 나 세 션 과 프로 세 스 그룹 에 로그 인 합 니 다.Linux 의 프로 세 스 와 제어 터미널, 로그 인 세 션 과 프로 세 스 그룹 간 의 관계: 프로 세 스 는 하나의 프로 세 스 그룹 에 속 합 니 다. 프로 세 스 그룹 번호 (GID) 는 프로 세 스 팀장 의 프로 세 스 (PID) 입 니 다.로그 인 세 션 은 여러 프로 세 스 그룹 을 포함 할 수 있 습 니 다. 이 프로 세 스 그룹 은 제어 단말 기 를 공유 합 니 다. 이 제어 단말 기 는 보통 프로 세 스 를 만 드 는 로그 인 터미널 입 니 다. 제어 단말 기 는 로그 인 세 션 과 프로 세 스 그룹 이 부모 프로 세 스에 서 계승 되 는 것 입 니 다. 우리 의 목적 은 프로 세 스 의 영향 을 받 지 않도록 하 는 것 입 니 다. 방법 은 첫 번 째 점 을 바탕 으로 setsid () 를 호출 하 는 것 입 니 다.프로 세 스 를 세 션 팀장 으로 만 들 기:
if (setsid() == -1)
{
printf("setsid is failed
");
}
setsid () 호출 에 성공 하면 프로 세 스 는 새로운 세 션 팀장 과 새로운 프로 세 스 팀장 이 되 고 원래 로그 인 세 션 과 프로 세 스 그룹 과 분 리 됩 니 다. 세 션 과정 이 제어 단말기 에 대한 독점 성 때문에 프로 세 스 는 제어 단말기 와 분 리 됩 니 다.3) 프로 세 스 가 제어 단말 기 를 다시 여 는 것 을 금지 합 니 다. (이 단 계 는 있 으 나 마 나 합 니 다. 상황 에 따라) 프로 세 스 는 터미널 이 없 는 세 션 팀장 이 되 었 습 니 다. 그러나 제어 단말 기 를 다시 열 어 달라 고 신청 할 수 있 습 니 다. 프로 세 스 가 더 이상 세 션 팀장 이 되 지 않도록 프로 세 스 가 제어 단말 기 를 다시 여 는 것 을 금지 할 수 있 습 니 다.
if(pid=fork()) exit(0); // , ( )
4) 열 린 파일 이 있 으 면 열 린 파일 설명 자 를 닫 습 니 다.프로 세 스 는 부모 프로 세 스 를 만 드 는 데 서 열 린 파일 설명 자 를 계승 합 니 다. 닫 지 않 으 면 시스템 자원 을 낭비 하여 프로 세 스 가 있 는 파일 시스템 을 지우 지 못 하고 예상 치 못 한 오 류 를 일 으 킬 수 있 습 니 다.
for(i=0;i<=getdtablesize();i++)
close(i)
5) 현재 작업 디 렉 터 리 (상황 에 따라) 프로 세 스 활동 을 변경 할 때 작업 디 렉 터 리 가 있 는 파일 시스템 을 해제 할 수 없습니다. 일반적으로 작업 디 렉 터 리 를 루트 디 렉 터 리 로 변경 해 야 합 니 다. 핵심 을 저장 해 야 하 는 프로 세 스 는 작업 디 렉 터 리 를 특정 디 렉 터 리 로 변경 합 니 다.
chdir("/tmp")
6) 파일 을 재 설정 하여 마스크 프로 세 스 를 만 듭 니 다. 부모 프로 세 스에 서 파일 을 계승 하여 마스크 를 만 듭 니 다. 데 몬 이 만 든 파일 의 액세스 위 치 를 수정 할 수 있 습 니 다. 이 를 방지 하기 위해 파일 을 마스크 로 만 듭 니 다.
umask(0);
ok, 기본 절차 가 완료 되 었 습 니 다. nginx 의 damon 프로 세 스 는 절차 1, 2, 6 만 있 습 니 다. 보통 이 3 단계 만 있 으 면 됩 니 다. 하지만 복잡 한 상황 은 절차 에 따라 쓰 십시오.다음 에 우 리 는 하나의 예 를 보고 있다.
하위 프로 세 스에 서 파일 을 열 고 파일 에 데 이 터 를 기록 합 니 다. 일정한 조건 을 충족 시 킬 때 데 몬 이 종 료 됩 니 다.
void daemon_fork()
{
pid_t pid;
pid = fork();
if (pid > 0)
{
printf("parent is exit
");
exit(0);// 1
}
else if (pid < 0)
{
printf("fork is failed
");
exit(-1);
}
else
{
if (setsid() == -1)// 2
{
printf("setsid is failed
");
}
umask(000);// 6
printf("child is working
");
FILE *fp = fopen("test.txt", "a");
if (fp == NULL)
{
kill(pid, SIGTERM);
}
//do something
int i = 0;
for (;;)
{
fprintf(fp, "%s", (u_char*)("I am the deamon two
"));
fprintf(fp, "i = %d
", ++i);
sleep(10);
if (i > 10)
{
fclose(fp);
kill(pid, SIGTERM);
}
}
}
}
http://blog.csdn.net/xiaoliangsky/article/details/39998373
참고:
http://blog.csdn.net/theone10211024/article/details/13774669
http://blog.chinaunix.net/uid-25365622-id-3055635.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단! Certbot을 사용하여 웹 사이트를 SSL(HTTPS)화하는 방법초보자가 인프라 주위를 정돈하는 것은 매우 어렵습니다. 이번은 사이트를 간단하게 SSL화(HTTP에서 HTTPS통신)로 변경하는 방법을 소개합니다! 이번에는 소프트웨어 시스템 Nginx CentOS7 의 환경에서 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.