В чем проблема с этой очень простой C-программой?(вызывает утечку памяти) - PullRequest
2 голосов
/ 06 июня 2019

У меня есть очень простая программа на C, которую я использую для выполнения системного вызова php каждую секунду, чтобы выполнить php-скрипт, который отправляет ожидающее push-уведомление в базе данных в Apple. Но в любом случае эта программа вызывает переполнение памяти примерно через 10 часов, поэтому я сократил время ожидания между созданием потока с 1 с до 10000 мкс, и в режиме реального времени с htop я мог видеть, что память увеличивалась и никогда не уменьшалась. Вот программа:

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

typedef struct {
    char* script_path ;
} arg_for_script ;

static void *start_instance(void *_args)
{
    int id = abs(pthread_self());
    arg_for_script* args = _args ;

    printf("[SERVICE] start php script on thread %d\n",id);
    fflush(stdout);
    char cmd[200] ;

    sprintf(cmd, "php -f %s %d", args->script_path, id );

    system(cmd);

    printf("[SERVICE] end of script on thread %d\n", id);
    fflush(stdout);



    pthread_exit(NULL);
}

int main(int argc, char* argv[])
{


    if(argc < 2)
    {
        fprintf(stderr, "[SERVICE] Path of php notification script must be filled\n");
        fflush(stderr);
        return EXIT_FAILURE;
    }

    arg_for_script args ;

    args.script_path = argv[1];

    pthread_attr_t tattr ;
    struct sched_param param;
    param.sched_priority = 1 ;

    pthread_attr_init(&tattr);

    pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&tattr, SCHED_FIFO);
    pthread_attr_setschedparam(&tattr, &param);



    while(1) {
        pthread_t thrd;

      //  if(pthread_create(&thrd, &tattr, start_instance, (void *)&args) == -1) {
        if(pthread_create(&thrd, NULL, start_instance, (void *)&args) == -1)
        {
            fprintf(stderr, "[SERVICE] Unable to create thread\n");
            fflush(stderr);
            return EXIT_FAILURE;
        }

        usleep( 10000);
    }

  //  pthread_attr_destroy(&tattr);
    return EXIT_SUCCESS ;

}

Я немного знаю C и помню, что мне нужно освободить только выделенную память с помощью malloc. Здесь я не делаю такое динамическое распределение памяти. Так почему же эта программа увеличивает использование памяти?

1 Ответ

4 голосов
/ 06 июня 2019

Вы не звоните pthread_join() и не используете pthread_detach(), поэтому ресурсы, выделенные для потока, не освобождаются.А именно, каждый поток имеет свой собственный стек, что, вероятно, является причиной увеличения потребления памяти.

Некоторые замечания о вашей реализации: Поскольку вы планируете выполнять сценарий PHP с system() и на самом деле не должны работатьдля общих переменных или файловых дескрипторов лучше использовать fork() и один из вариантов exec().Это создаст новый процесс без промежуточного шага создания потока.Также не рекомендуется использовать system(), потому что это часто позволяет использовать программу, когда входные данные не должным образом очищены.В этом случае все может быть хорошо, если вы вызываете его только вручную.

...