将指针传递给 pthread 函数会导致丢失其结构

Passin a pointer to a pthread function result in losing his structure

我正在尝试启动一个线程并给他一个指向结构的指针。但是函数接收到的指针不正确。我的结构中有一部分是正确的,但其他的则不是。

这是启动线程的函数:

void start_pointer(struct fsm_pointer *pointer) {
    if ( pointer->started != 0 ){
        printf("CRITICAL : A pointer must be started only once");
        return;
    }
    pthread_create(&pointer->thread, NULL, &pointer_loop, (void *)pointer);
    pointer->started = 1;
}

这里是 pointer_loop 函数:

void *pointer_loop(void * _pointer) {
    struct fsm_pointer * pointer = _pointer; // cast void pointer
    struct fsm_context init_context = {
        .event = event,
        .fnct_args = step.args,
    };
    // call pointer structure member => SEGFAULT
    pointer->current_step.fnct(&init_context); 
    return NULL;
}

结构定义如下:

struct fsm_pointer{
    pthread_t thread;
    pthread_mutex_t mutex_event;
    pthread_cond_t cond_event;
    struct fsm_event input_event;
    struct fsm_step current_step;
    unsigned short started;
};

struct fsm_step{
    void (*fnct)(const struct fsm_context *);
    void * args;
    struct fsm_trans transition;
};

::编辑::
这是 pointerstep 结构出现的地方:

struct fsm_pointer * create_pointer(struct fsm_step first_step)
{
    struct fsm_pointer *pointer = malloc(sizeof(pointer));
    pointer->thread = 0;
    pointer->mutex_event = PTHREAD_MUTEX_INITIALIZER;
    pointer->cond_event = PTHREAD_COND_INITIALIZER;
    pointer->input_event = _NONE_EVENT;
    pointer->current_step = first_step;
    pointer->started = 0;
    return pointer;
}

struct fsm_step create_step(void (*fnct)(const struct fsm_context *), void *args)
{
    struct fsm_step result = {
            .fnct = fnct,
            .args = args,
            .transition = TRANS_ENDPOINT,
    };
    return result;
}

这是管理它的函数:

void test_new_fsm(){
    struct fsm_step step_0 = create_step(&callback, NULL);
    struct fsm_pointer *fsm = create_pointer(step_0);

    start_pointer(fsm);
    sleep(5);
    pthread_join(fsm->thread, NULL);
    sleep(1);
    free(fsm);
}

回调函数只是为了测试:

void callback(const struct fsm_context *context) {
    printf("Callback : event uid : %d \n", context->event.uid);
}

::/编辑::

当我在段错误之前使用调试器 (gdb) 时,我可以看到指针的地址是正确的(与线程创建之前相同)并且 started 变量正确设置为 1。但是 fnct 指针是 NULL 会产生段错误。

如果在创建线程之前执行与 pointer_loop 完全相同的代码(具有正确的变量名),则没有任何问题。

那么,有人知道发生了什么吗,或者这只是一个明显的错误,以至于一天多的调试还不够?

谢谢。

您没有显示 pointer 指向的 struct fsm_pointer 类型的对象开始存在的代码,但大概它正在被修改,或者它的生命周期结束,没有同步新创建的线程对其的访问。除非你在线程启动函数和调用者中有同步,以排除并发access/end-of-lifetime,你将不得不等到你加入线程释放这个结构或以其他方式允许它的生命周期结束。

struct fsm_pointer *pointer = malloc(sizeof(pointer));

应该是:

struct fsm_pointer *pointer = malloc(sizeof(struct fsm_pointer));

struct fsm_pointer *pointer = malloc(sizeof(*pointer));