Ограничить время выполнения функции в с

Я хотел бы ограничить выполнение функции в чистом C, не останавливая всю программу.

Я полагаю, что самым близким моментом на stackru.com было последнее замечание в этой теме: как ограничить время выполнения функции в C/POSIX?

Был некоторый разговор об использовании setjmp и longjm, помещенных после функции, чтобы ограничить время, но поток умер.

Есть ли кто-нибудь, кто знает, действительно ли это возможно?

ура

2 ответа

Я вижу два варианта: первый проверяет время каждые несколько строк кода и return если это слишком много, но я не думаю, что это хорошая идея.

Во-вторых, вы можете использовать темы. Запустите две функции одновременно, одну синхронизирующую другую, если время слишком велико, то первая убивает. Теперь я почти уверен, что в Windows и Linux есть разные библиотеки для создания потоков, поэтому вы можете попробовать использовать библиотеку, которая работает на всех платформах, например, эта может быть http://openmp.org/wp/

Я не слишком знаком с этой библиотекой и потоками в целом, но я надеюсь, что это поможет

Хотя может быть полезно опубликовать мое решение. Это комбинация этого поста http://cboard.cprogramming.com/c-programming/148363-limit-execution-time-function.html и примера IPC TPL, найденного здесь: https://github.com/troydhanson/tpl/blob/master/doc/examples.txt.

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>
#include <string.h>
#include "tpl.h"

//This example contains two different parts:
        //1) The alarm is a execution timer for the function doWork
        //2) There is a need, that if the execution exits correctly, that the chid value of i, that we are modifying be passes

typedef struct TEST_STRUCT
{
        int i;
        double sum;
} testStruct;

int doWork(testStruct * ts)
{
        int y;
        for(y=0; y<3; y++)
        {
                sleep(1);
                printf("Working: %d\n", ts->i);
                ts->i++;
                ts->sum += (double)ts->i;
        }
        return 0;
}
int main()
{

        testStruct * ts = (testStruct *)(calloc(1, sizeof(testStruct)));
        ts->i = 7;
        ts->sum = 4.0;

        tpl_node *tn;
        int fd[2];
        pipe(fd);
        int y;
        for(y=0; y<10; y++)
        {
                pid_t childPID = fork();
                if (childPID==0)
                {
                        unsigned secsLeft;
                        alarm(10);
                        doWork(ts);

                        printf("\t->%d\n", ts->i);
                        printf("\t->%p\n", (void*) &ts->i);

                        tn = tpl_map("S(if)", ts);
                        tpl_pack( tn, 0 );
                        tpl_dump( tn, TPL_FD, fd[1]);
                        tpl_free( tn );

                        secsLeft = alarm(0);
                        exit(0);
                }
                else
                {
                        //IMPORTANT TO PUT IT HERE: In case the buffer is too big, TPL_DUMP will wait until it can send another and hang
                        tn = tpl_map( "S(if)", ts );
                        tpl_load( tn, TPL_FD, fd[0]);

                        int status;
                        wait(&status);

                        if(WIFSIGNALED(status))
                        {
                                // child was interrupted
                                if (WTERMSIG(status) == SIGALRM)
                                {
                                        printf("Interrupted\n");
                                        // child interrupted by alarm signal
                                }
                                else
                                {
                                        printf("Should not happend\n");
                                         // child interrupted by another signal
                                }
                        }
                        else
                        {
                                tpl_unpack(tn,0);
                                tpl_free( tn );

                                printf("\t->%d\n", ts->i);
                                printf("\t->%p\n", (void*) &ts->i);
                                printf("Success\n");
                        }
                }
        }
        return 0;
}

По сути, мы разветвляем программу, в которой ребенок выполняет задание, а родитель ожидает его завершения. Ребенок содержит тревогу, которая, если истина сигнализирует родителю, что он существовал таким образом. Если он завершается (как показано в этом примере), дочерний объект отправляет объектную функцию родителю в виде буфера TPL.

Другие вопросы по тегам