Linux 백 엔 드 서비스 개발 노트 1 - Linux 프로 세 스 Daemon 화 상세 설명 [전재]

6689 단어 【Linux】
원문:http://linux.chinaitlab.com/soft/881436.html
 1.  데 몬 프로필
    데 몬 프로 세 스 는 엘 프 프로 세 스 가 생존 기간 이 긴 프로 세 스 라 고도 합 니 다. 시스템 이 불 러 올 때 시작 하고 시스템 관 비 를 할 때 종 료 됩 니 다.엘 프 프로 세 스 가 터미널 을 제어 하지 않 아서 배경 에서 실 행 됩 니 다.데 몬 은 매우 유용 한 프로 세 스 입 니 다.Linux 의 대부분의 서버 는 데 몬 으로 이 루어 집 니 다.예 를 들 어 인터넷 서버 inetd, 웹 서버 httpd 등 이다.동시에 데 몬 은 많은 시스템 작업 을 수행 합 니 다.예 를 들 어 작업 계획 프로 세 스 crond, 인쇄 프로 세 스 lpd 등.
    모든 엘 프 프로 세 스 는 슈퍼 유저 (사용자 ID 0) 의 우선권 으로 실 행 됩 니 다.제어 단말 기 를 가 진 엘 프 프로 세 스 가 없습니다. 제어 이름 은 물음표 로 설정 되 어 있 고 터미널 프론트 데스크 톱 프로 세 스 그룹 ID 는 - 1 로 설정 되 어 있 습 니 다.update 를 제외 한 모든 엘 프 프로 세 스 는 그룹의 첫 번 째 프로 세 스 이 며, 대화 기의 첫 번 째 프로 세 스 이 며, 이 프로 세 스 그룹 과 대화 기의 유일한 프로 세 스 입 니 다.그래서 엘 프 프로 세 스 의 부모 프로 세 스 는 모두 init 프로 세 스 입 니 다.
    데 몬 의 가장 중요 한 기능 은 배경 에서 실행 되 는 것 입 니 다.이 점 에서 도스 의 상주 메모리 프로그램 인 TSR 은 이와 비슷 하 다.그 다음으로 데 몬 은 실행 전의 환경 과 격 리 되 어야 합 니 다.이 환경 은 닫 히 지 않 은 파일 설명자, 제어 단말기, 세 션 과 프로 세 스 그룹, 작업 디 렉 터 리, 파일 마스크 생 성 등 을 포함한다.이 환경 들 은 보통 부모 프로 세 스 (특히 셸) 에서 데 몬 을 계승 합 니 다.마지막 으로 데 몬 의 시작 방식 은 특별한 점 이 있 습 니 다.리 눅 스 시스템 이 시 작 될 때 시작 스 크 립 트/etc/rc. d 에서 시작 할 수 있 습 니 다. 작업 계획 프로 세 스 crond 에서 시작 할 수 있 고 사용자 터미널 (보통 셸) 에서 도 실행 할 수 있 습 니 다.
    2.  데 몬 만 들 기 키 단계
    데 몬 을 만 드 는 데 몇 가지 중요 한 절차 가 있 고 주의해 야 할 부분 이 있 습 니 다.
    몇 가지 중요 한 절 차 는 다음 과 같다.
    1: 파일 생 성 권한 지우 기
    2: fork 를 호출 한 다음 부모 프로 세 스 를 종료 합 니 다.
    3: 새 세 션 을 만 들 기 위해 setsid 를 호출 합 니 다. 세 가지 목적 으로 호출 프로 세 스 a: 새 세 션 의 첫 번 째 프로 세 스 가 되 었 습 니 다. b: 새 프로 세 스 의 팀장 프로 세 스 가 되 었 습 니 다. c: 터미널 을 제어 하지 않 았 습 니 다.
    4: 작업 디 렉 터 리 전환
    5: 필요 하지 않 은 파일 설명 자 를 닫 습 니 다.
    6: 일부 데 몬 은/dev/null 을 열 어 파일 설명자 0, 1, 2 를 가지 게 합 니 다. 표준 입력 과 쓰기 표준 출력 을 읽 으 려 는 라 이브 러 리 과정 은 아무런 효과 가 없습니다.
    주의 할 점
    1: 데 몬 이 터미널 을 제어 하지 않 기 때문에 표준 입 출력 오류 와 대화 할 수 없습니다. printf 를 사용 할 수 없습니다. 보통 syslog 로 데 몬 의 인쇄 정 보 를 해결 합 니 다.
    3.  데 몬 만 들 기 상세 절차
    1. 백 스테이지 에서 실행 합 니 다.
    제어 단말 기 를 끊 지 않도록 Daemon 을 배경 에 넣 고 실행 합 니 다.방법 은 프로 세 스 에서 fork 를 호출 하여 부모 프로 세 스 를 종료 시 키 고 Daemon 이 하위 프로 세 스 의 배경 에서 실행 하도록 하 는 것 입 니 다.
    if(pid=fork())
    exit(0);//부모 프로 세 스 입 니 다. 부모 프로 세 스 를 끝내 고 하위 프로 세 스 를 계속 합 니 다.
    2. 제어 단말기 에서 벗 어 나 세 션 과 프로 세 스 그룹 에 로그 인 합 니 다.
    먼저 Linux 의 프로 세 스 와 제어 단말 기 를 소개 할 필요 가 있 습 니 다. 로그 인 세 션 과 프로 세 스 그룹 간 의 관 계 는 프로 세 스 그룹 에 속 합 니 다. 프로 세 스 그룹 번호 (GID) 는 프로 세 스 팀장 의 프로 세 스 번호 (PID) 입 니 다.로그 인 세 션 은 여러 프로 세 스 그룹 을 포함 할 수 있 습 니 다.이 프로 세 스 그룹 들 은 제어 단말 기 를 공유 합 니 다.이 제어 단말 기 는 보통 프로 세 스 를 만 드 는 로그 인 터미널 입 니 다.
    터미널 을 제어 합 니 다. 로그 인 세 션 과 프로 세 스 그룹 은 보통 부모 프로 세 스에 서 물 려 받 습 니 다.우리 의 목적 은 그것들 을 벗 어 나 그들의 영향 을 받 지 않도록 하 는 것 이다.방법 은 첫 번 째 점 을 바탕 으로 setsid () 를 호출 하여 프로 세 스 를 세 션 팀장 으로 만 드 는 것 입 니 다.
    setsid();
    설명: 프로 세 스 가 세 션 팀장 일 때 setsid () 호출 에 실 패 했 습 니 다.첫 번 째 는 프로 세 스 가 세 션 팀장 이 아니 라 는 것 을 보증 합 니 다.setsid () 호출 에 성공 하면 프로 세 스 는 새로운 세 션 팀장 과 새로운 프로 세 스 팀장 이 되 고 원래 로그 인 세 션 과 프로 세 스 그룹 과 분 리 됩 니 다.세 션 프로 세 스 가 제어 단말기 에 대한 독점 성 때문에 프로 세 스 는 제어 단말기 와 분리 된다.
    3. 프로 세 스 가 제어 단말 기 를 다시 여 는 것 을 금지 합 니 다.
    현재 프로 세 스 는 터미널 이 없 는 세 션 팀장 이 되 었 습 니 다.하지만 제어 단말 기 를 다시 열 어 달라 고 신청 할 수 있다.프로 세 스 가 더 이상 세 션 팀장 이 되 지 않도록 제어 단말 기 를 다시 여 는 것 을 금지 할 수 있 습 니 다.
    if(pid=fork())
    exit(0);//첫 번 째 하위 프로 세 스 를 끝내 고 두 번 째 하위 프로 세 스 를 계속 합 니 다 (두 번 째 하위 프로 세 스 는 더 이상 세 션 팀장 이 아 닙 니 다)
    4. 열 린 파일 설명자 닫 기
    프로 세 스 는 부모 프로 세 스 를 만 드 는 데 서 열 린 파일 설명 자 를 계승 합 니 다.닫 지 않 으 면 시스템 자원 을 낭비 하여 프로 세 스 가 있 는 파일 시스템 을 제거 할 수 없고 예상 치 못 한 오 류 를 일 으 킬 수 있 습 니 다.다음 방법 으로 닫 기:
    for(i=0;i<= max;i++) close(i);
    5. 현재 작업 디 렉 터 리 변경
    프로 세 스 가 활성 화 될 때 작업 디 렉 터 리 가 있 는 파일 시스템 을 해제 할 수 없습니다.일반적으로 작업 디 렉 터 리 를 루트 디 렉 터 리 로 바 꿔 야 합 니 다.핵심 을 저장 해 야 할 경우, 실행 로 그 를 쓰 는 프로 세 스 는 작업 디 렉 터 리 를/tmp, chdir ("/") 와 같은 특정 디 렉 터 리 로 변경 합 니 다.
    6. 파일 재 설정 마스크 만 들 기
    프로 세 스 는 부모 프로 세 스 를 만 드 는 데 서 파일 을 계승 하여 마스크 를 만 들 었 습 니 다.데 몬 이 만 든 파일 의 액세스 위 치 를 수정 할 수 있 습 니 다.이 를 방지 하기 위해 파일 을 마스크 로 만 들 고 지우 기: umask (0);
    7. SIGCHLD 신호 처리
    SIGCHLD 신 호 를 처리 하 는 것 은 필수 가 아 닙 니 다.그러나 일부 프로 세 스, 특히 서버 프로 세 스 는 요청 이 올 때 하위 프로 세 스 처리 요청 을 생 성 합 니 다.부모 프로 세 스 가 하위 프로 세 스 가 끝 날 때 까지 기다 리 지 않 으 면 하위 프로 세 스 는 좀 비 프로 세 스 (zombie) 가 되 어 시스템 자원 을 점용 합 니 다.부모 프로 세 스 가 하위 프로 세 스 가 끝 날 때 까지 기다 리 면 부모 프로 세 스 의 부담 이 증가 하고 서버 프로 세 스 의 병행 성능 에 영향 을 줍 니 다.Linux 에서 SIGCHLD 신호 조작 을 SIG 로 간단하게 설정 할 수 있 습 니 다.IGN.
    signal(SIGCHLD,SIG_IGN);
    이렇게 하면 내부 핵 은 하위 프로 세 스 가 끝 날 때 좀 비 프로 세 스 가 생기 지 않 는 다.BSD 4 와 달리 BSD 4 에 서 는 하위 프로 세 스 가 끝 날 때 까지 명시 적 으로 기 다 려 야 좀 비 프로 세 스 를 풀 수 있다.
    4.  참조 코드
    
#include   
#include   
#include   
#include   
#include   
#include   
void daemonize(const char *cmd)  
{  
	int                  i, fd0, fd1, fd2;  
	pid_t                pid;  
	struct rlimit        rl;  
	struct sigaction	sa;  
	/* 
	* Clear file creation mask. 
	*/  
	umask(0);  
	/* 
	* Get maximum number of file descriptors. 
	*/  
	if (getrlimit(RLIMIT_NOFILE, &rl) < 0)  
		printf("%s: can't get file limit", cmd);  
	/* 
	* Become a session leader to lose controlling TTY. 
	*/  
	if ((pid = fork()) < 0)  
		printf("%s: can't fork", cmd);  
	else if (pid != 0) /* parent */  
		exit(0); 
		
	setsid();  
	/* 
	* Ensure future opens won't allocate controlling TTYs. 
	*/  
	sa.sa_handler = SIG_IGN;  
	sigemptyset(&sa.sa_mask);  
	sa.sa_flags = 0;  
	if (sigaction(SIGHUP, &sa, NULL) < 0)  
		printf("can't ignore SIGHUP");  
	if ((pid = fork()) < 0)  
		printf("%s: can't fork", cmd);  
	else if (pid != 0) /* parent */  
		exit(0);  
	/* 
	* Change the current working directory to the root so 
	* we won't prevent file systems from being unmounted. 
	*/  
	if (chdir("/") < 0)  
		printf("can't change directory to /");  
	/* 
	* Close all open file descriptors. 
	*/  
	if (rl.rlim_max == RLIM_INFINITY)  
		rl.rlim_max = 1024;  
	for (i = 0; i < rl.rlim_max; i++)  
		close(i);  
	/* 
	* Attach file descriptors 0, 1, and 2 to /dev/null. 
	*/  
	fd0 = open("/dev/null", O_RDWR);  
	fd1 = dup(0);  
	fd2 = dup(0);  
	/* 
	* Initialize the log file. 
	*/  
	openlog(cmd, LOG_CONS, LOG_DAEMON);  
	if (fd0 != 0 || fd1 != 1 || fd2 != 2) {  
		syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);  
		exit(1);  
	}  
	syslog(LOG_DEBUG, "daem ok ");  
}  

int main()  
{  
	daemonize("test");  
	while(1);//            
}  

어떻게 진행 과정 을 죽 입 니까?
ps axj 명령 을 사용 하여 프로그램의 pid 를 찾 습 니 다.
그리고 kill pid 를 사용 하면 됩 니 다.

좋은 웹페이지 즐겨찾기