C ++ Timed Process

0

Я пытаюсь настроить тестовое программное обеспечение для кода, который уже написан (что я не могу изменить). Проблема, с которой я сталкиваюсь, заключается в том, что она зависает на определенных вызовах, поэтому я хочу попытаться реализовать что-то, что убьет процесс, если он не завершится через х секунд.

Эти два метода, которые я пытался решить эту проблему, заключались в использовании fork или pthread, оба пока не работали для меня. Я не уверен, почему pthread не работает, я предполагаю, потому что статический вызов, который я использовал для создания потока, имел некоторые проблемы с памятью, необходимой для запуска функции, которую я вызывал (я постоянно получал segfault, в то время как функция, которую я тестировал). Вилка работала изначально, но во второй раз я бы расколол процесс, он не смог бы проверить, закончил ли ребенок или нет.

В терминах полу-псевдокода это то, что я написал

test_runner()
{
    bool result;

    testClass* myTestClass = new testClass();

    pid_t pID = fork();
    if(pID == 0) //Child
    {
        myTestClass->test_function(); //function in question being tested
    }
    else if(pID > 0) //Parent
    {
        int status;
        sleep(5);
        if(waitpid(0,&status,WNOHANG) == 0)
        {
            kill(pID,SIGKILL); //If child hasn't finished, kill process and fail test
            result = false;
        }
        else
            result = true;
    }
}

Этот метод работал для первоначального теста, но затем, когда я перейду к проверке второй функции, if (waitpid (0, & status, WNOHANG) == 0) вернет, что ребенок закончил, даже если этого не произошло.

Метод pthread рассматривал эти строки

bool result;

test_runner()
{
    long thread = 1;

    pthread_t* thread_handle = (pthread_t*) malloc (sizeof(pthread_t));
    pthread_create(&thread_handle[thread], NULL, &funcTest, (void *)&thread); //Begin class that tests function in question

    sleep(10);

    if(pthread_cancel(thread_handle[thread] == 0))
        //Child process got stuck, deal with accordingly
    else
        //Child process did not get stuck, deal with accordingly
}

static void* funcTest(void*)
{
    result = false;

    testClass* myTestClass = new testClass();
    result = myTestClass->test_function();
}

Очевидно, что происходит немного больше, чем то, что я показал, я просто хотел опустить общую идею. Я предполагаю, что я ищу, если есть лучший способ справиться с проблемой, подобной этой, или, может быть, если кто-то увидит какие-то вопиющие проблемы с тем, что я пытаюсь сделать (я относительно новичок в C++). Как я уже упоминал, мне не разрешено входить в код, который я настраиваю для тестового программного обеспечения, что мешает мне помещать обработчики сигналов в функцию, которую я тестирую. Я могу только вызвать функцию, а затем обработать ее оттуда.

  • 1
    У вас есть пид дочернего процесса. Почему бы не передать его в waitpid?
  • 1
    Вы не должны ждать exaxt ребенка Pid pID вместо 0 в waitpid(0,&status,WNOHANG) ?
Показать ещё 2 комментария
Теги:
multithreading
pthreads
fork

1 ответ

2

Если С++ 11 является законным, вы можете использовать future с wait_for для этой цели.

Например (живая демонстрация):

std::future<int> future = std::async(std::launch::async, [](){ 
    std::this_thread::sleep_for(std::chrono::seconds(3));
    return 8;  
});

std::future_status status = future.wait_for(std::chrono::seconds(5));
if (status == std::future_status::timeout) {
    std::cout << "Timeout" <<endl ;
} else{
    cout << "Success" <<endl ;
} // will print Success

std::future<int> future2 = std::async(std::launch::async, [](){ 
    std::this_thread::sleep_for(std::chrono::seconds(3));
    return 8;  
});

std::future_status status2 = future2.wait_for(std::chrono::seconds(1));
if (status2 == std::future_status::timeout) {
    std::cout << "Timeout" <<endl ;
} else{
    cout << "Success" <<endl ;
} // will print Timeout

Еще одна вещь:

Согласно документации с использованием waitpid с 0:

что означает ожидание любого дочернего процесса, идентификатор группы процессов которого совпадает с идентификатором вызывающего процесса.

Избегайте использования pthread_cancel это, вероятно, не очень хорошая идея.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню