首页 > 解决方案 > C++ pthread - 如何从线程函数返回一个值而不等待完成?

问题描述

我遵循基本的 c++ 教程来制作多个线程。我有绘制循环,在框架中我启动了几个线程。我不等待 pthread_join 的线程结果,而是继续绘制其他对象。如果适当对象的并条机检测到所有线程都已完成,则我启动“threadsFinished”函数。在我写的时候,我不使用 pthread_join,相反,我喜欢将结果写入启动这些线程的对象,在我的例子中,它是类 Program。我通过线程函数中的指针访问“程序”对象,我可以在这里将结果写入该对象,但它是线程安全的吗?或者我应该将互斥锁与 Program 对象一起使用?

这是我的代码:

void Program::onDraw(Matrix *matrix) {
    fireThreads();
    ....

    if (threadsStarted && threadsFinishedCount == NUM_THREADS) {
        threadsFinished();
    }
    ...draw other stuff, progress bar etc... 
}

void *Program::threadFunction(void *threadData) {
    thread_data *data = static_cast<thread_data*>(threadData);
    Program *program = static_cast<Program*>(data->owner);
    program->threadsFinishedCount++;

    pthread_exit(NULL);
}

void Program::fireThreads() {
    if (threads == NULL) {
        threads = new pthread_t[NUM_THREADS];
        threadData = new thread_data[NUM_THREADS];
    }

    int rc;
    int i;

    threadsFinishedCount = 0;
    threadsStarted = true;

    for( i = 0; i < NUM_THREADS; i++ ) {
        threadData[i].threadId = i;
        threadData[i].owner = this;

        rc = pthread_create(&threads[i], NULL, updateDB, (void *)&threadData[i]);

        if (rc) {
            ...
        }
    }
}

使用的变量是这样定义的:

class Program {
...
    static void *threadFunction(void *threadId);
    bool threadsStarted;
    volatile int threadsFinishedCount;
...
}

标签: c++multithreading

解决方案


我可以在这里将结果写入该对象,但它是线程安全的吗?

不,它不是线程安全的。在 C/C++ 中,如果多个线程同时访问同一个对象,并且这些访问中至少有一个是修改,那么就会出现数据竞争,这会导致未定义的行为。线程同步原语,如互斥锁和atomic,是此规则的例外,因此您必须使用其中之一来实现线程安全。

请注意,这volatile不是一个例外,而且从来都不是对对象的并发访问volatile仍然会导致竞争条件。


推荐阅读