创建多个分叉线程的正确方法

proper way to create multiple forked threads

我正在为一些嵌入式代码创建一个计时器函数,这将允许我在某个进程 运行ning 时绕过某些 GPIO 检查,即当计时器为 运行 时以非阻塞方式运行。

这似乎 运行 前 11 次操作很好,但每次,在第 11 次迭代时系统都会崩溃。可能的罪魁祸首是定时器线程的处理方式。我的猜测是我没有正确处理一些内存清理,这会导致某种内存泄漏。但是我真的不确定。

我可以通过调试跟踪看到线程在每次迭代后退出。

定时器代码如下:

#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 函数的调用。它在整个系统的许多地方使用,从来都不是问题。

希望有人能指出我正确的方向。

但是您的代码确实 post 不足以确定问题可能出在哪里,但我认为这可能值得一提:

一个普遍的问题是您拥有的示例代码是关于创建线程的开环;那就是没有什么可以限制它的,如果你的实现有一个特别慢的线程退出处理,你可能有很多僵尸线程躺在那里还没有死。

在典型的嵌入式/实时系统中,您希望将资源分配移出主循环,因为它通常是不确定的。因此,您通常会创建一个计时器线程,然后停放它直到需要它为止:

void *TimerThread(void *arg) {
     while (sem_wait(&request) == 0) {
           msp432e4_timer(void *arg);
     }
     return 0
}
void TimerStart(void) {
     sem_post(&request);
}