правильный способ создания нескольких разветвленных потоков - PullRequest
1 голос
/ 27 мая 2020

Я создаю функцию таймера для небольшого фрагмента встроенного кода, который позволит мне обойти определенные проверки GPIO во время выполнения определенного процесса, т.е. когда таймер работает неблокирующим образом.

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

Благодаря трассировке отладки я вижу, что поток завершается после каждой итерации.

Вот код таймера:

#include <time.h>
#include <semaphore.h>
#include <pthread.h>

#include <msp432e4_timer.h>

extern void TaskSleep(uint32_t delay);

static bool timerActive;
static sem_t timerSem;

pthread_t timerThread;
pthread_attr_t attrs;
struct sched_param priParam;


static void *msp432e4_timer(void *argUnused) {
    sem_wait(&timerSem);
    timerActive = true;
    sem_post(&timerSem);

    TaskSleep(40);

    sem_wait(&timerSem);
    timerActive = false;
    sem_post(&timerSem);

    return (NULL);
}

void initTimer() {
    int retc;
    pthread_attr_init(&attrs);
    priParam.sched_priority = 1;
    retc = pthread_attr_setschedparam(&attrs, &priParam);
    retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
    retc |= pthread_attr_setstacksize(&attrs, 1024);
    if (retc != 0) {
        // failed to set attributes
        while (1) {}
    }

    timerActive = false;
    if((sem_init(&timerSem, 0, 0)) != 0) {
        while(1);
    }
    sem_post(&timerSem);
}

/*
 * return true on starting a new timer
 * false implies timer already active
 */
void timerStart() {
    int retc;
    retc = pthread_create(&timerThread, &attrs, msp432e4_timer, NULL);
    if (retc != 0) {
        // pthread_create() failed
        while (1) {}
    }
}

/* return true if timer active */
bool timerCheck() {
    bool retval;
    sem_wait(&timerSem);
    retval = timerActive;
    sem_post(&timerSem);
    return(retval);
}

Функция TaskSleep - это вызов функции FreeRTOS TaskDelay. Он используется во многих точках системы и никогда не был проблемой.

Надеюсь, кто-нибудь сможет указать мне правильное направление.

1 Ответ

2 голосов
/ 27 мая 2020

Но вы на самом деле не опубликовали достаточно вашего кода, чтобы определить, где могут быть проблемы, но я подумал, что об этом стоит упомянуть:

Общая проблема заключается в том, что ваш образец кода открыт l oop при создании потока; то есть нет ничего, что могло бы его ограничить, и если ваша реализация имеет особенно медленную обработку выхода потока, у вас может быть много зомбированных ie потоков, которые еще не умерли. time, вы хотите переместить распределение ресурсов из main l oop, поскольку оно часто недетерминировано c. Итак, чаще вы создаете поток таймера и паркуете , пока он не понадобится:

void *TimerThread(void *arg) {
     while (sem_wait(&request) == 0) {
           msp432e4_timer(void *arg);
     }
     return 0
}
void TimerStart(void) {
     sem_post(&request);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...