C++ std::thread 无效使用 void 表达式

Posted

技术标签:

【中文标题】C++ std::thread 无效使用 void 表达式【英文标题】:C++ std::thread invalid use of void expression 【发布时间】:2014-01-25 04:38:17 【问题描述】:

我的线程程序有问题。我知道问题是什么,只是不知道如何解决。我正在设置任意数量的线程来创建 mandelbrot 集,然后将其写入 ppm 文件。我正在使用 std::thread 的向量并调用 Mandelbrot 类成员函数来执行线程。问题发生在这里。我正在调用编译器不喜欢的 void(void) 函数。我该如何解决这个问题,以便线程执行 void(void) 函数?我的代码如下:

main.cpp

int main(int argc, char **argv) 
   const unsigned int WIDTH = 1366;
   const unsigned int HEIGHT = 768;
   int numThreads = 2;

   Mandelbrot mandelbrot(WIDTH, HEIGHT);

   if(argc > 1) 
      numThreads = atoi(argv[1]);
   

   std::vector<std::thread> threads;

   for(int i = 0; i < numThreads; ++i) 
      threads.emplace_back(mandelbrot.mandelbrotsetThreaded());
   

   for(int i = 0; i < numThreads; ++i) 
      threads[i].join();
   

   return 0;

mandelbrot.cpp

void Mandelbrot::mandelbrotsetThreaded() 
   while(true) 
      int row = 0;
      
         std::lock_guard<std::mutex> lock(row_mutex);
         row = cur_row++;
      
      if(row == width) return;
      createMandelbrotSet(row);
   

【问题讨论】:

@paxdiablo 给了你正确的答案,所以这里有一些建议:不要使用互斥锁来保护cur_row,而是将其设为std::atomic&lt;&gt; 感谢您的建议。我以前从未对线程做过任何事情。这对我来说都是新的。 【参考方案1】:
threads.emplace_back(mandelbrot.mandelbrotsetThreaded());
//                                                   ^^
//                                               note this!

那条小线实际上会调用 mandelbrot.mandelbrotsetThreaded() 并尝试使用返回值传递给threads.emplace_back()。当返回类型指定为void 时,它会发现这相当困难:-)

你想要的是函数(地址)本身,而不是函数的结果,比如:

threads.emplace_back(mandelbrot.mandelbrotsetThreaded);

【讨论】:

正确使用此类函数的正确方法如下:threads.emplace_back(&Mandelbrot::mandelbrotsetThreaded, mandelbrot);

以上是关于C++ std::thread 无效使用 void 表达式的主要内容,如果未能解决你的问题,请参考以下文章

C++的std:thread是怎么进行参数传递的

新线程导致问题 C++

C++ 多线程std::thread 详解

C++ 多线程std::thread 详解

使用 std::thread 在 C++ 中的单独线程中执行每个对象

C++ 中的 std::thread 库是不是支持嵌套线程?