daemon 프로 세 스 는 왜 포크 를 두 번 이나 해 야 합 니까? 배경 프로그램 과 구별 합 니까?

5188 단어 linux
daemon 프로 세 스 는 배경 데 몬 입 니 다. Liux 아래 server 는 모두 daemon 프로 세 스 입 니 다.대부분의 개발 자 들 이 데 몬 프로 세 스 를 어떻게 쓰 는 지 알 고 있 을 것 이 라 고 믿는다.그러나 다른 한편, 대부분의 사람들 은 왜 이렇게 해 야 하 는 지 모 르 고 많은 사람들 이 어 딘 가 에서 함 수 를 복사 합 니 다.그러나 구체 적 으로 왜 이렇게 이 루어 졌 는 지 는 확실 하지 않다.
daemon 함수 가 존재 하 는 이 유 는 터미널 을 제어 하 는 이유 가 있 기 때 문 입 니 다.시내 에 가서 이 신 호 를 처리 하 는 데 부족 한 동작 을 받 으 면 프로 세 스 가 종 료 됩 니 다.이 신 호 는 단말기 에서 특수 버튼 을 두 드 려 서 발생 할 것 이다.
daemon 함수 의 흔 한 구현 을 붙 입 니 다:
int daemon(void)
{
    pid_t pid = fork();
    if( pid != 0 ) exit(0);//parent
    //first children
    if(setsid() == -1)
    {
       printf("setsid failed
"); assert(0); exit(-1); } umask(0); pid = fork(); if( pid != 0) exit(0); //second children chdir ("/"); for (int i = 0; i < 3; i++) { close (i); } int stdfd = open ("/dev/null", O_RDWR); dup2(stdfd, STDOUT_FILENO); dup2(stdfd, STDERR_FILENO); return 0; }

1. 첫 번 째 fork 의 역할 은 셸 이 이 명령 이 종료 되 었 다 고 생각 하고 터미널 입력 에 걸 지 않 아 도 된다 는 것 입 니 다.또 하나의 역할 은 뒤쪽 setsid 를 위 한 서비스 입 니 다.setsid 호출 자 는 프로 세 스 팀장 (group leader) 이 될 수 없습니다. 이 때 부모 프로 세 스 는 프로 세 스 팀장 입 니 다.
    
2. setsid () 는 이 함수 의 가장 중요 한 호출 입 니 다.그것 은 데 몬 함수 가 하고 싶 은 대부분의 일 을 완성 했다.전체 함 수 를 호출 하 다.하위 프로 세 스 는 세 션 팀장 (sid = = pid) 이자 프로 세 스 팀장 (pgid = = pid) 이 며 원래 제어 터미널 에서 벗 어 났 습 니 다.이 단계 에 이 르 러 서 는 기본적으로 제어 단말기 가 어떻게 되 든 상관없다.새로운 프로 세 스 는 그 신 호 를 받 지 못 할 것 이다.
3  、앞의 두 단 계 를 거 쳐 기본적으로 하고 싶 은 것 은 모두 했다.두 번 째 포크 는 필수 가 아 닙 니 다.오픈 소스 서비스 도 많이 봤 어 요.포크 의 두 번 째 주요 목적 은프로 세 스 가 제어 단말 기 를 다시 여 는 것 을 방지 합 니 다.제어 단말 기 를 여 는 전제조건 은 이 프로 세 스 가 세 션 팀장 이 어야 하기 때문이다.다시 한 번 fork, 하위 프로 세 스 ID! =sid (sid 는 프로 세 스 부모 프로 세 스 의 sid) 입 니 다.그래서 새로운 제어 단말 기 를 열 수 없습니다.
    daemon 의 목적 은 터미널 에서 발생 하 는 일부 신 호 를 방지 하여 프로 세 스 를 종료 시 키 는 것 입 니 다.위의 함 수 는 signal 함 수 를 직접 호출 하여 처리 하지 않 았 습 니 다.간접 적 으로 fork 와 setsid 함 수 를 통 해 더 적은 코드 를 사용 하여 우아 하 게 처리 합 니 다.경직 된 진행 으로 오 해 를 받 는 이 유 는 이렇게 처리 해 야 한다.
    물론 위의 함수 처럼 실현 되 지 않 는 프로그램 도 많다.신 호 를 무시 하 는 방식 으로 처리 하 는 것 이다.이것 도 사실 괜찮다. 왜냐하면 이 신호 들 은 유용 한 가치 가 매우 적기 때문이다.기본적으로 오 살 이 없 는 상황 을 간과 하 다.어차피 최종 목적 을 달성 하면 돼.모든 큰길 은 로마 로 통한다.
   제어 단말기 에 어떤 신호 가 발생 하 는 지 나열 해 보 자.프로그램 에서 이 신 호 를 잘 처리 하면 상기 함수 가 실현 하 는 목적 을 달성 할 수 있다.
   //백 엔 드 프로 세 스 읽 기 / 쓰기 터미널 입력 은 다음 두 개의 신 호 를 만 들 거나 터미널 에 존재 하지 않 는 상황 을 제어 하여 읽 기와 쓰기 가 발생 합 니 다.
   signal(SIGTTOU, SIG_IGN);
   signal(SIGTTIN, SIG_IGN);
   //CTRL - C, CTRL - \ CTRL - Z 를 누 르 면 프론트 프로 세 스 그룹 에 다음 신 호 를 보 냅 니 다.
   signal(SIGINT,  SIG_IGN );
   signal(SIGQUIT, SIG_IGN );
   signal(SIGTSTP, SIG_IGN );
   
   //터미널 이 끊 기 면 세 션 팀장 이나 고아 프로 세 스 팀 의 모든 구성원 에 게 다음 신 호 를 보 냅 니 다.
   signal(SIGHUP,  SIG_IGN );
   터미널 셸 에서 도 신호 가 나 올 수 있 으 니 주목 해 야 한다.
   signal(SIGCONT, SIG_IGN );
   signal(SIGSTOP, SIG_IGN );
  위의 신 호 는 프로 세 스 를 종료 하 는 것 이 아니 라 프로그램 이 부족 해 야 합 니 다. (SIG DFL) 자체 동작 은 무시 (SIG IGN) 입 니 다.하지만 위 에 적 혀 있 는 대로 문제 가 되 지 는 않 을 겁 니 다.
dup 2 (stdfd, STDOUT FILENO) 는 이 프로그램의 표준 출력 을 블랙홀 로 재 설정 합 니 다. dup 와 dup 2 는 기 존 파일 설명 자 를 복사 하여 두 파일 설명 자 를 같은 file 구조 체 로 가리 킬 수 있 습 니 다.
#include int dup(int newfd); int dup2(int newfd, int oldfd);        다음은 두 함수 의 용법 과 차 이 를 간단 한 예 로 설명 한다.
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
 int main(void)
 {
     int fd, save_fd;
     char msg[] = "This is a test of dup() & dup2()
"; int test; fd = open("somefile", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if(fd<0) { perror("open"); exit(1); } save_fd = dup(STDOUT_FILENO); // save_fd STDOUT——FILENO, save_fd printf("save_fd=%d
",save_fd); // test=dup2(fd, STDOUT_FILENO); // STDOUT_FILENO fd , STDOUT_FILENO somefile printf("dup2_1=%d
",test); // , somefile close(fd); write(STDOUT_FILENO, msg, strlen(msg)); // STDOUT_FILENO somefile , // somefile test=dup2(save_fd, STDOUT_FILENO); // STDOUT_FILENO save_fd , printf("dup2_2=%d
",test); // , write(STDOUT_FILENO, msg, strlen(msg)); // STDOUT_FILENO close(save_fd); return 0; }

데 몬 은 & 로 끝 나 는 배경 프로그램 과 어떤 차이 가 있 습 니까?
가장 큰 차 이 는 몇 가지 가 있다.
1) 데 몬 은 터미널 콘 솔 에서 완전히 벗 어 났 고 배경 프로그램 은 터미널 에서 완전히 벗 어 나 지 않 았 으 며 터미널 이 닫 히 지 않 기 전에 터미널 로 결 과 를 출력 합 니 다.
2) 데 몬 은 터미널 콘 솔 을 닫 을 때 영향 을 받 지 않 으 며, 배경 프로그램 은 사용자 가 종료 할 때 중단 되 며, nohug xxx & 형식 으로 실행 되 어야 영향 을 피 할 수 있 습 니 다.
3) 데 몬 의 세 션 그룹 과 현재 디 렉 터 리, 파일 설명자 가 독립 되 어 있 습 니 다.백 엔 드 실행 은 터미널 에서 포크 를 한 번 진행 하여 프로그램 을 백 엔 드 에서 실행 시 켰 을 뿐 변경 되 지 않 았 습 니 다.

좋은 웹페이지 즐겨찾기