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

时间:2012-10-20 02:36:00

标签: c++ c multithreading thread-safety pthreads

在C / C ++中如何让线程(POSIX pthreads / Windows线程)给我一个安全的方法来将进度传递回执行进程或我决定执行的工作的主线程与线程。

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

2 个答案:

答案 0 :(得分:4)

解决这个问题的最好方法是使用C ++原子。在一些可见的地方宣布:

std::atomic<int> my_thread_progress(0);

在一个简单的例子中,这应该是一个静态变量,在一个更复杂的地方,这应该是管理线程或类似东西的某个对象的数据字段。

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

  1. 您可以保证在任何平台上都可以正常工作,即使在16位CPU或任何不寻常的硬件上也是如此;
  2. 您的代码将更易于阅读。 Reader会立即看到这是共享变量,而不会发表任何评论。一旦使用load / store方法进行更新,就可以更轻松地了解正在发生的事情。
  3. 修改

    英特尔®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位边界上对齐的双字

答案 1 :(得分:4)

我将假设一个非常简单的主线程和一个函数的情况。我推荐的是每次启动线程时都会传入指向原子的指针(如上面的Kirill所建议)。假设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;
}

我认为你会做你想做的事。我省略了对线程的轮询,但是你明白了。我传入一个主线程和子线程都知道的对象(在这种情况下是atomic<int>变量),它们都可以更新和/或轮询结果。如果您没有使用完整的C ++ 11线程/原子支持编译器,请使用您的平台所确定的任何内容,但始终有一种方法可以将变量(至少为void*)传递给线程函数。这就是你如何获得通过非静态来回传递信息的东西。