向C ++中的主线程报告线程进度

Laa*_*vaa 4 c c++ multithreading pthreads thread-safety

在C / C ++中,我该如何使线程(POSIX pthreads / Windows线程)成为一种安全的方法,以便根据执行进度或我决定使用该线程执行的工作的进度,将进度传递回主线程。

是否可以按百分比报告进度?

Kir*_*lev 5

解决此问题的最佳方法是为此使用C ++原子。在足够可见的地方声明:

std::atomic<int> my_thread_progress(0);
Run Code Online (Sandbox Code Playgroud)

在简单的情况下,它应该是静态变量,而在更复杂的地方,它应该是管理线程或类似对象的某个对象的数据字段。

在许多平台上,这会有些偏执,因为几乎所有地方的整数读写操作都是原子的。仍然使用原子位是因为:

  1. 您将保证它可以在任何平台上正常工作,甚至在16位CPU或任何异常硬件上也可以;
  2. 您的代码将更易于阅读。读者将立即看到这是共享变量,而无需添加任何注释。一旦使用load/ store方法进行更新,就可以更轻松地了解正在发生的事情。

编辑

英特尔®64和IA-32架构软件开发人员手册组合卷:1、2A,2B,2C,3A,3B和3C(http://download.intel.com/products/processor/manual/325462.pdf

第3A卷:8.1.1保证的原子操作

Intel486处理器(以及以后的更新处理器)保证了以下基本内存操作将始终以原子方式执行:

  • 读取或写入字节
  • 读取或写入在16位边界上对齐的单词
  • 读取或写入在32位边界上对齐的双字


Kev*_*son 5

我将假设一个非常简单的主线程和一个函数实例。我建议每次启动线程时都传递一个指向原子的指针(如上面的基里尔所建议)。在这里假设C ++ 11。

using namespace std;

void threadedFunction(atomic<int>* progress)
{
    for(int i = 0; i < 100; i++)
    {
        progress->store(i);  // updates the variable safely
        chrono::milliseconds dura( 2000 );
        this_thread::sleep_for(dura); // Sleeps for a bit
    }
    return;
}

int main(int argc, char** argv)
{
    // Make and launch 10 threads
    vector<atomic<int>> atomics;
    vector<thread> threads;
    for(int i = 0; i < 10; i++)
    {
        atomics.emplace_back(0);
        threads.emplace_back(threadedFunction, &atomics[i]);
    }

    // Monitor the threads down here
    // use atomics[n].load() to get the value from the atomics
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想那会做你想要的。我省略了轮询线程,但您明白了。我要传入一个主线程和子线程都知道的对象(在本例中为atomic<int>变量),它们都可以更新和/或轮询结果。如果您使用的不是完整的C ++ 11线程/原子支持编译器,请使用平台确定的功能,但是总有一种方法可以将变量(至少是void*)传递到线程函数中。这就是通过非静态方法来回传递信息的方式。