Linux 백 엔 드 서비스 개발 노트 1 - Linux 프로 세 스 Daemon 화 상세 설명 [전재]
6689 단어 【Linux】
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 를 사용 하면 됩 니 다.