[APUE] 재독 프로세스 관계

3303 단어 필기
이 장은 가장 이해하기 어렵고 가장 난해한 장이다.프로세스 그룹,session,단말기,작업 간의 관계와 개념을 주로 설명한다.
1. 터미널 로그인
터미널 로그인은 init에서 fork getty 프로세스를 직접 가져옵니다. getty는 execle ("/usr/bin/login", "login", "-p",username, (char* 0,envp) 와 같은 문장을 호출하여 로그인 과정을 완성합니다.
올바르게 로그인하면login은 현재 작업 디렉터리를 사용자의 시작 디렉터리 (chdir) 로 변경하고chown을 호출하여 터미널의 소유권을 변경합니다.setgid 및 initgroups 설정 프로세스의 그룹 ID를 호출합니다.그리고login이 얻은 정보 초기화 환경: 시작 디렉터리, 셸, 사용자 이름, 기본 시스템 경로 PATH. 마지막으로login 프로세스는 로그인 사용자의 사용자 ID (setuid) 로 바뀌고 이 사용자의 로그인 셸을 호출합니다.
execl("/bin/sh","-sh", (char*)0)
2. 프로세스 그룹 개념
#include 
#include 
pid_t getpgrp(void);
int setpgid(pid_t pid, pid_t pgid)
그룹 ID를 변경하고 설정하는 예
#include 
#include 
#include 

int main()
{
    pid_t pid;
    if((pid=fork())<0)
    {
        printf("fork error
"); return 1; } else if(pid==0) { printf("Child pid=%d,gid=%d
", getpid(),getpgrp()); sleep(3); setpgid(pid,pid); printf("Child pid=%d,gid=%d
", getpid(),getpgrp()); } else { printf("Parent pid=%d,gid=%d
", getpid(),getpgrp()); if(wait(NULL)==-1) { printf("wait error
"); } printf("Parent pid=%d,gid=%d
", getpid(),getpgrp()); } }

3. 세션 개념
setsid를 통해 원래session에서 벗어나 새session을 만들 수 있습니다.팀장 프로세스가 setsid를 호출할 수 없습니다. 그렇지 않으면 오류가 발생합니다.호출 후 새session이 기존 제어 단말기에서 벗어납니다.
setsid는 일반적으로 정령 프로세스를 만들 때 호출됩니다.
4.session, 터미널과 프로세스 그룹 관계 제어
  • 세션 하나에 제어 단말기가 있을 수도 있고 없을 수도 있다
  • 제어 단말기와 연결하는 대화 기간의 첫 번째 프로세스를 구축하여 제어 단말기
  • 를 위한
  • session에는 프론트 데스크톱 프로세스 조합이 있고 몇 개의 프론트 데스크톱 프로세스 그룹이 있다
  • SIGINT와 SIGQUIT는 모든 프론트 데스크 프로세스에 발송
  • 터미널 인터페이스에서 연결 끊김이 감지되면 제어 프로세스에 끊김 신호를 보냅니다
  • 5. 고아 진행팀
    부모 프로세스가 종료된 프로세스 그룹을 고아 프로세스 그룹이라고 합니다.부모 프로세스가 종료되면 자식 프로세스는 init 프로세스에 의해 입양됩니다.부모 프로세스가 끝나면 kernel은 하위 프로세스에 SIGHUP 및 SIGCONT 신호를 보냅니다.
    다음 demo, 하위 프로세스가 SIGHUP을 받는 signal 함수를 등록하지 않으면 하위 프로세스가 종료됩니다.
    하위 프로세스가 터미널을 읽으려고 시도하면 실패합니다.
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    static void pr_ids(char* name)
    {
        printf("%s: pid=%d, ppid=%d, pgid=%d
    ",name, getpid(),getppid(),getpgrp()); fflush(stdout); } static void sig_hup(int signo) { printf("Received signal hup
    "); return; } int main() { pid_t pid; if((pid=fork())<0) { printf("fork error
    "); exit(-1); } else if (pid>0) //parent { sleep(5); exit(0); } else { pr_ids("child"); /* if (signal(SIGHUP,sig_hup)==SIG_ERR) { printf("signal error
    "); return -1; } */ kill(getpid(),SIGTSTP); pr_ids("child"); char c; if(read(0,&c,1)!=1) printf("read error, errno =%d, reason=%s
    ", errno, strerror(errno)); exit(0); } }

    좋은 웹페이지 즐겨찾기