프로세스에서 제어 터미널로 신호 보내기

프로세스에서 제어 터미널로 신호 보내기

다음 작업을 수행하는 깔끔하고 우아한 방법을 알고 싶습니다. foo이라는 쉘 스크립트의 일부로 내부적으로 실행되는 C++ 프로그램을 작성한다고 가정해 보겠습니다 bar.sh. 쉘 스크립트를 foo백그라운드 프로세스로 실행한 다음 기다리기를 원합니다.~까지실행이 foo내가 선택한 라인에 도달하면 bar실행이 계속되어야 합니다.

명확성을 위해 다음은 더미 예입니다 bar.sh.

#!/bin/bash
./foo
wait 
echo "WAKING UP"

이것은 foo:

#include <iostream>
 int main(){
    for (int i = 0; i < 1000000; i++){
          std::cout << i << std::endl;

          if (i == 50){
              //Wake up bash!
          }
    }
 }

wait 명령이 반복 50에서 중지 되도록 foo수정 하고 싶습니다 . 따라서 for 루프가 에 도달하면 깨어나서 WAKING UP을 인쇄 해야 합니다 . 물론 계속해서 달릴 수도 있습니다.barbarfoofooi = 50barfoo

이 효과를 얻으려면 이러한 프로그램을 어떻게 수정해야 합니까?

답변1

fork()이것이 기본적으로 + 의 의미입니다 setsid().

bar.sh

#!/bin/bash

echo "Launching foo"
./foo
echo "Waking up"

foo.c

#include <stdio.h>
#include <unistd.h>


int main(int ac, char ** av)
{
    int pid;
    for (int i=0; i<5; i++) {
        sleep(1);
    }
    printf("OK, we count to 5.\n");

    /* 
     * Here we fork() + setsid() to detach from parent process
     * Return value of fork is 0 if you are in child, pid of the child 
     * if you're in the parent process 
     */
    pid = fork();
    if (pid == 0) {
        setsid();
        printf("We forked, still running but shell may be back\n");
        sleep(5);
        printf("Exiting ...\n");
    } else {
        return 0;
    }
}

결과

/tmp/pouet$ ps aux|grep foo
me  8595  0.5  0.1 217548 18576 pts/12   T    14:17   0:01 vim foo.c 
me  9167  0.0  0.0  12716   912 pts/12   S+   14:21   0:00 grep foo
/tmp/pouet$ ./bar.sh 
Launching foo
OK, we count to 5.
We forked, still running but shell may be back
Waking up
/tmp/pouet$ ps aux|grep foo
me  8595  0.5  0.1 217548 18576 pts/12   T    14:17   0:01 vim foo.c 
me  9189  0.0  0.0   4160    76 ?        Ss   14:21   0:00 ./foo 
me  9192  0.0  0.0  12716   940 pts/12   S+   14:21   0:00 grep foo
/tmp/pouet$ Exiting ...

/tmp/pouet$ ps aux|grep foo
me  8595  0.5  0.1 217548 18576 pts/12   T    14:17   0:01 vim foo.c
me  9212  0.0  0.0  12716   908 pts/12   S+   14:21   0:00 grep foo

답변2

한 가지 방법은 fork먼저 부모님을 떠나는 것입니다.

#include <iostream>
#include <unistd.h>
#include <stdlib.h>

int main(){
    for (int i = 0; i < 1000000; i++){
        std::cout << i << std::endl;

        if (i == 50){
            if (fork() != 0) {
                _Exit(0);
            }
        }
    }
}

이로 인해 원치 않는 효과가 발생할 수 있으며, _Exit그 중 가장 확실한 것은 is를 사용하여 피할 수 있습니다.

또 다른 방법은 C++ 프로그램이 상위 프로그램에 신호를 보내는 것입니다. 이것은 또한 내장된 대기를 종료합니다(POSIX인지 아니면 단지 bashism인지 기억이 나지 않습니다).

#include <iostream>
#include <unistd.h>
#include <stdlib.h>

int main(){
    for (int i = 0; i < 1000000; i++){
        std::cout << i << std::endl;

        if (i == 50){
            kill(getppid(), SIGINT);
        }
    }
}

여기서 주목할 점은 스크립트와 C++ 프로그램 간의 프로세스입니다. trap쉘 스크립트에서 신호를 처리하는 방법을 찾고 싶을 수도 있습니다 .

관련 정보