2012-10-20 17 views
3

在C/C++中如何让线程(POSIX pthreads/Windows线程)为我提供一个安全的方法,以将进度传递回执行进度的主线程或我已决定用线程执行的工作。在C++中向主线程报告线程进度

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

+1

哪个操作系统?什么类型的应用程序?如果它是一个GUI应用程序,只需使用PostMessage即可。 – enhzflep

回答

4

解决这个问题的最好方法就是使用C++原子。声明在一些可见的不够到位:

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

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

在很多平台上,这将会有点偏执狂,因为几乎在任何地方对整数的读写操作都是原子的。使用原子的位仍然是因为:

  1. 您将保证这可以在任何平台上正常工作,即使在16位CPU或任何不寻常的硬件上;
  2. 您的代码将更易于阅读。读者将立即看到这是共享变量,而不会发表任何评论。一旦它将用load/store方法进行更新,将更容易捕捉正在发生的事情。

EDIT

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位的边界
+0

嗨基里尔,我需要一个机制,从线程发送信息说线程A通过消息传递系统主线程 – Laavaa

+1

如果这是简单的状态数据,声明几个原子变量。否则,请使用STL队列并使用STL互斥锁保护对此队列的访问。 –

3

我在对准一个双将假设一个非常简单的主线程和一个函数。我推荐的是每次启动线程时传递一个指向原子的指针(如上面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*)传递给线程函数。这就是你如何通过非静态信息来回传递信息。

+1

应该指出的是,指向矢量元素的指针并不安全。您调整'atomics'大小的事实可能会使传递给线程的指针无效。 – nwn

+1

你说得对。您必须首先保留所有空间,否则这些指针可能会失效。接得好。 LinkedList <>在这里是更好的选择,因为扩展它并不会使现有元素无效。 –