programing

exec() 함수와 그 패밀리를 설명해 주세요.

bestcode 2022. 7. 16. 15:12
반응형

exec() 함수와 그 패밀리를 설명해 주세요.

예요?exec()능능 및및 ???이 기능은 왜 사용되며 어떻게 작동합니까?

이 기능에 대해 아무나 설명해 주세요.

간단히 말하면 UNIX에서는 프로세스와 프로그램의 개념이 있습니다.프로세스는 프로그램이 실행되는 환경입니다.

UNIX의 「실행 모델」의 배후에 있는 간단한 생각은, 할 수 있는 조작이 2개 있다는 것입니다.

첫 번째는 에 대한 것으로, 현재 프로그램의 복제(대부분 상태 포함)를 포함하는 완전히 새로운 프로세스가 생성됩니다.어느 쪽이 부모이고 어느 쪽이 자식인지 파악할 수 있도록 하는 두 프로세스 사이에는 몇 가지 차이가 있습니다.

두 번째는 에 대한 것으로, 현재 프로세스의 프로그램을 새로운 프로그램으로 대체합니다.

이러한 두 가지 간단한 작업을 통해 전체 UNIX 실행 모델을 구성할 수 있습니다.


위의 세부사항을 추가하려면:

「 」의 fork() ★★★★★★★★★★★★★★★★★」exec()는 UNIX가 새로운 프로세스를 시작하는 매우 간단한 방법을 제공한다는 점에서 UNIX의 정신을 보여줍니다.

fork()콜은 현재 프로세스의 거의 모든 면에서 동일한 복제를 만듭니다(예를 들어 일부 구현에서는 리소스 제한 등 모든 것이 복사되는 것은 아니지만 가능한 한 가까운 복사본을 만드는 것이 좋습니다).프로세스 콜은 1개뿐 fork()하지만 그 통화에서 두 가지 프로세스가 돌아온다 - 이상하게 들리지만 정말 우아하다.

새로운 프로세스(자녀라고 불린다)는 다른 프로세스 ID(PID)를 취득해, 낡은 프로세스(부모)의 PID를 부모 PID(PPID)로서 가집니다.

가 현재 완전히 코드를 인지 알 수즉, 어느 것이 반환 코드인지 알 수 있어야 합니다.fork()는 이0이 (자녀가 0이 경우).자녀가 0이 되고 부모가 자녀의 PID를 취득합니다(이 경우).fork()에러가 발생하고, 자녀는 생성되지 않고 부모에게 에러 코드가 표시됩니다).

의 PID를 그 PID와 , 할 수 가 항상 하려면 , 「PID」, 「PID」, 「PID」, 「PID」, 「PID」, 「PID」, 「PID」, 「PID」, 「PID」를 호출합니다).getppid()를 참조해 주세요.

exec()를 새로운 .call은 새로운 프로그램으로 바꿉니다.현재 프로세스 공간에 프로그램을 로드하여 진입점에서 실행합니다.

so,는,fork() ★★★★★★★★★★★★★★★★★」exec()는 현재 프로세스의 자녀로 새로운 프로그램을 실행하기 위해 종종 순차적으로 사용됩니다.은 보통 여러분이 하려고 할 마다 이렇게 .find- 껍데기가 갈라지고, 그 다음에 아이가 장전합니다.findI/O를 사용하다

하지만 함께 사용할 필요는 없습니다.에서 불러주는 fork() 없이exec()예를 들어 프로그램에 부모 코드와 자녀 코드가 모두 포함되어 있는 경우(각 구현에 제한이 있을 수 있습니다).

이것은 단순히 TCP 포트에서 리슨하고 부모가 리슨으로 돌아가는 동안 특정 요청을 처리하기 위해 자신의 복사본을 포크하는 데몬에 매우 많이 사용되었습니다(그리고 지금도 마찬가지입니다).이 경우 프로그램에는 부모 코드와 자녀 코드가 모두 포함됩니다.

이 끝났다는 다른 도 다른 을 실행할 필요가 fork(),exec() 다음에 또 한 번.wait()/waitpid()아이를 위해서.할 수 .exec().

된 UNIX가 .fork()카피 온 라이트은, 의 카피를 입니다.fork()프로그램이 그 공간에서 뭔가를 바꾸려고 할 때까지요이 기능은 다음 프로그램에서만 사용할 수 있습니다.fork()가 아니라exec()프로세스 공간 전체를 복사할 필요가 없습니다.Linux에서는fork()페이지 테이블과 새로운 태스크 구조의 복사본만 만듭니다.exec()는, 2개의 프로세스의 메모리를 「분리」하는 귀찮은 작업을 실시합니다.

이 경우,exec following이라고 불립니다.fork(대부분 이렇게 됩니다) 프로세스 공간에 쓰기가 발생하고 수정이 허용되기 전에 하위 프로세스에 대해 복사됩니다.

Linux에는vfork()두 프로세스 간에 거의 모든 것이 공유되기 때문에 더욱 최적화되어 있습니다.그 때문에 아이가 할 수 있는 일에 일정한 제한이 있어 아이가 전화를 걸 때까지 부모가 멈춘다.exec()또는_exit().

두 프로세스가 같은 스택을 공유하기 때문에 부모를 중지해야 합니다(그리고 자녀는 현재 기능에서 복귀할 수 없습니다).이는 기존 사용 사례에서 약간 더 효율적입니다.fork()곧 이어서exec().

유념해 주세요.exec콜(execl,execle,execve등) 하지만exec여기서 문맥상으로는 그 중 하나를 의미합니다.

다음 다이어그램은 일반적인 데이터 보호 기능을 보여 줍니다.fork/exec조작이 필요한 경우bash셸을 사용하여 디렉토리 목록과ls명령어:

+--------+
| pid=7  |
| ppid=4 |
| bash   |
+--------+
    |
    | calls fork
    V
+--------+             +--------+
| pid=7  |    forks    | pid=22 |
| ppid=4 | ----------> | ppid=7 |
| bash   |             | bash   |
+--------+             +--------+
    |                      |
    | waits for pid 22     | calls exec to run ls
    |                      V
    |                  +--------+
    |                  | pid=22 |
    |                  | ppid=7 |
    |                  | ls     |
    V                  +--------+
+--------+                 |
| pid=7  |                 | exits
| ppid=4 | <---------------+
| bash   |
+--------+
    |
    | continues
    V

exec() 패밀리의 기능에는 다음과 같은 동작이 있습니다.

  • l : 인수는 문자열 목록으로 main()에 전달됩니다.
  • v : 인수는 문자열 배열로 main()에 전달됩니다.
  • p : 실행 중인 새 프로그램을 검색하는 경로/초
  • e : 발신자가 환경을 지정할 수 있습니다.

혼재시킬 수 있기 때문에, 다음과 같은 것이 있습니다.

  • int execl(const char *path, const char *path, const char *par
  • int execlp(const char *file, const char *file, const char *files
  • int execle(const char *path, const char *path, ..., char * const envp [ ] );
  • int execv(const char *path, char *const argv [ ] );
  • int execvp(const char *file, char *const argv[]);
  • int execvpe(const char *file, char *const argv[], char *const envp[]);

모든 경우 initial 인수는 실행할 파일의 이름입니다.

자세한 내용은 exec(3) man 페이지를 참조하십시오.

man 3 exec  # if you are running a UNIX system

exec함수 패밀리를 사용하면 프로세스가 실행 중인 이전 프로그램을 대체하여 다른 프로그램을 실행할 수 있습니다.예를 들어, 당신이 전화하면

execl("/bin/ls", "ls", NULL);

그 다음에ls프로그램은 호출한 프로세스의 프로세스 ID, 현재 작업 중인 dir 및 사용자/그룹(액세스 권한)을 사용하여 실행됩니다.execl이후 원래 프로그램은 더 이상 실행되지 않습니다.

새로운 프로세스를 시작하려면fork시스템 콜이 사용됩니다.원본을 교체하지 않고 프로그램을 실행하려면fork,그리고나서exec.

exec 기능 및 그 패밀리는 무엇입니까?

execfunction family는 파일 실행에 사용되는 모든 함수입니다.execl,execlp,execle,execv,그리고.execvp모두 의 프론트 엔드입니다.execve다양한 호출 방법을 제공합니다.

이 기능이 사용되는 이유는 무엇입니까?

EXEC 기능은 파일(프로그램)을 실행할 때 사용합니다.

어떻게 작동하는지도요.

현재 프로세스 이미지를 실행한 이미지로 덮어쓰는 방식으로 작동합니다.현재 실행 중인 프로세스(exec 명령을 호출한 프로세스)를 실행한 새 프로세스로 바꿉니다(종료).

자세한 내용은 이 링크를 참조하십시오.

exec와 병용되는 경우가 많다.fork저도 당신이 물어본 것을 보았기 때문에, 그것을 염두에 두고 논의하겠습니다.

exec현재 프로세스를 다른 프로그램으로 변환합니다.'닥터 후'를 보신 적이 있으시다면, 마치 그가 재생하는 것과 같습니다. 그의 오래된 몸이 새로운 몸으로 교체됩니다.

및 에서의 이 exec이 OS에 이 있는지 하기 위해 리소스입니다.exec첫 번째 인수)는 현재수(「」( 「」)를 하는 ).execcall하고 콜을 합니다).argv ★★★★★★★★★★★★★★★★★」envpexec이 새로운 가상 메모리 맵의 영역을 호출합니다.에도 몇 가지 할 수 , 이 있던 은 이 에 의해 호출되었습니다.execID가 되지만, 를 호출한 프로세스 ID를 공유합니다.exec(exec이 실패하지 않는 한) 정지합니다.

이렇게 하는 이유는 runnanewprogram을 이렇게 두 단계로 분리하면 두 단계 사이에 몇 가지 작업을 수행할 수 있기 때문입니다.가장 일반적인 방법은 새 프로그램에 특정 파일이 특정 파일 설명자로 열려 있는지 확인하는 것입니다.(여기서 파일 기술자는 다음 파일 기술자와 동일하지 않습니다.FILE *단, , ,,int」를 참조해 주세요.이를 통해 다음 작업을 수행할 수 있습니다.

int X = open("./output_file.txt", O_WRONLY);

pid_t fk = fork();
if (!fk) { /* in child */
    dup2(X, 1); /* fd 1 is standard output,
                   so this makes standard out refer to the same file as X  */
    close(X);

    /* I'm using execl here rather than exec because
       it's easier to type the arguments. */
    execl("/bin/echo", "/bin/echo", "hello world");
    _exit(127); /* should not get here */
} else if (fk == -1) {
    /* An error happened and you should do something about it. */
    perror("fork"); /* print an error message */
}
close(X); /* The parent doesn't need this anymore */

이것으로 실행이 완료됩니다.

/bin/echo "hello world" > ./output_file.txt

명령어 셸에서 가져옵니다.

프로세스가 fork()를 사용하면 자신의 복사본이 생성되고 이 복사본이 프로세스의 하위 복사본이 됩니다.fork()는 커널에서 두 번 반환되는 Linux의 clone() 시스템 호출을 사용하여 구현됩니다.

  • 0이 아닌 값(자녀의 프로세스 ID)이 부모에게 반환됩니다.
  • 값 0이 아이에게 반환됩니다.
  • 메모리 부족 등의 문제로 인해 자녀가 정상적으로 생성되지 않을 경우 -1이 fork()로 반환됩니다.

예를 들어 이것을 이해합시다.

pid = fork(); 
// Both child and parent will now start execution from here.
if(pid < 0) {
    //child was not created successfully
    return 1;
}
else if(pid == 0) {
    // This is the child process
    // Child process code goes here
}
else {
    // Parent process code goes here
}
printf("This is code common to parent and child");

이 예에서는 자 프로세스 내에서 exec()이 사용되지 않는다고 가정하고 있습니다.

그러나 부모와 자녀는 PCB(프로세스 제어 블록) 속성의 일부가 다릅니다.다음과 같습니다.

  1. PID - 자녀와 부모 모두 프로세스 ID가 다릅니다.
  2. 보류 중인 신호 - 하위는 부모의 보류 중인 신호를 상속하지 않습니다.생성 시 하위 프로세스에 대해 비어 있습니다.
  3. 메모리 잠금 - 자녀는 부모의 메모리 잠금을 상속하지 않습니다.메모리 잠금은 메모리 영역을 잠그는 데 사용할 수 있는 잠금으로, 이 메모리 영역을 디스크로 스왑할 수 없습니다.
  4. 레코드 잠금 - 자녀는 부모의 레코드 잠금을 상속하지 않습니다.레코드 잠금은 파일 블록 또는 파일 전체와 관련되어 있습니다.
  5. 프로세스 리소스 사용률 및 CPU 소비 시간은 하위 항목에 대해 0으로 설정됩니다.
  6. 또한 자녀는 부모로부터 타이머를 상속받지 않습니다.

하지만 아이의 기억은 어떤가요?어린이를 위해 새 주소 공간이 생성되었습니까?

정답은 '아니오'입니다.fork() 뒤에 부모와 자녀 모두 부모의 메모리주소 공간을 공유합니다.Linux 에서는, 이러한 주소 공간은 복수의 페이지로 분할됩니다.자녀가 부모 메모리 페이지 중 하나에 쓸 때만 해당 페이지의 복제본이 자식용으로 생성됩니다.이것은 카피 온 라이트(Copy on Write)라고도 합니다(자녀가 카피할 때만 부모 페이지를 카피합니다).

예를 들어 Copy on Write에 대해 설명하겠습니다.

int x = 2;
pid = fork();
if(pid == 0) {
    x = 10;
    // child is changing the value of x or writing to a page
    // One of the parent stack page will contain this local               variable. That page will be duplicated for child and it will store the value 10 in x in duplicated page.  
}
else {
    x = 4;
}

그런데 왜 카피 온 라이트가 필요한가?

일반적인 프로세스 작성은 fork()-exec() 조합을 통해 이루어집니다.먼저 exec()의 기능에 대해 설명하겠습니다.

exec() 함수 그룹은 자녀의 주소 공간을 새 프로그램으로 대체합니다.exec()이 자녀 내에서 호출되면 부모와는 완전히 다른 별도의 주소 공간이 생성됩니다.

fork()와 관련된 쓰기 메커니즘에 복사본이 없는 경우 하위 페이지에 대한 중복 페이지가 생성되고 모든 데이터가 하위 페이지에 복사됩니다.새로운 메모리를 할당하고 데이터를 복사하는 것은 매우 비용이 많이 드는 프로세스입니다(프로세서의 시간과 기타 시스템 리소스가 필요합니다).또한 대부분의 경우 아이가 exec()을 호출하여 아이의 메모리를 새 프로그램으로 대체한다는 것도 알고 있습니다.그래서 우리가 처음 복사한 복사본이 거기에 없었더라면 낭비였을 것입니다.

pid = fork();
if(pid == 0) {
    execlp("/bin/ls","ls",NULL);
    printf("will this line be printed"); // Think about it
    // A new memory space will be created for the child and that   memory will contain the "/bin/ls" program(text section), it's stack, data section and heap section
else {
    wait(NULL);
    // parent is waiting for the child. Once child terminates, parent will get its exit status and can then continue
}
return 1; // Both child and parent will exit with status code 1.

부모가 자식 프로세스를 기다리는 이유는 무엇입니까?

  1. 부모는 자식에게 작업을 할당하고 작업이 완료될 때까지 기다릴 수 있습니다.그러면 다른 작업을 수행할 수 있습니다.
  2. 자식이 종료되면 프로세스 제어 블록을 제외한 자식에 관련된 모든 리소스가 해방됩니다.지금 아이는 좀비 상태입니다.wait()를 사용하여 부모는 자녀의 상태를 조회한 후 커널에 PCB를 해방하도록 요청할 수 있습니다.부모가 wait를 사용하지 않는 경우, 아이는 좀비 상태를 유지합니다.

exec() 시스템콜이 필요한 이유는 무엇입니까?

exec()을 fork()와 함께 사용할 필요는 없습니다.자녀가 실행하는 코드가 부모와 관련된 프로그램 내에 있는 경우 exec()은 필요하지 않습니다.

하지만 아이가 여러 프로그램을 실행해야 하는 경우를 생각해 보세요.셸 프로그램의 예를 들어보겠습니다.find, mv, cp, date 등의 여러 명령을 지원합니다.이러한 명령어와 관련된 프로그램 코드를 하나의 프로그램에 포함하거나 필요할 때 자녀에게 이러한 프로그램을 메모리에 로드하는 것이 올바른가?

사용 사례에 따라 다릅니다.2^x 를 클라이언트에 반환하는 입력x 가 지정된 웹 서버가 있습니다.각 요청에 대해 웹 서버는 새 하위 항목을 생성하고 계산하도록 요청합니다.이를 계산하기 위해 별도의 프로그램을 작성하여 exec()을 사용하시겠습니까?아니면 그냥 부모 프로그램 안에 계산 코드를 쓰실 건가요?

보통 프로세스 작성에는 fork(), exec(), wait() 및 exit() 콜의 조합이 포함됩니다.

exec(3,3p)함수는 현재 프로세스를 다른 프로세스로 대체합니다.즉, 현재 프로세스가 중지되고 대신 다른 프로세스가 실행되어 원래 프로그램이 가지고 있던 리소스 중 일부를 차지합니다.

언급URL : https://stackoverflow.com/questions/4204915/please-explain-the-exec-function-and-its-family

반응형