繁体   English   中英

包含std :: threads的元素向量

[英]Vector of elements containing std::threads

我有一个包含std:thread对象的类Tester和一个Testerstd::vector 我知道我无法复制线程,所以push_back是不可能的,但为什么emplace_back不起作用? 我的代码中的副本在哪里?

#include <iostream>
#include <thread>
#include <vector>
#include <functional>
#include <unistd.h>

class Tester
{
public:
    Tester(std::function<void(void)> func) : 
        th(func)
    {
    }

    ~Tester()
    {
        th.join()
    }

private:
    std::thread th;
};

std::vector<Tester> testers;

void InnerHelloWorld()
{
    std::cout << "Hello from the inner word!\n";
}

int main() {
    std::cout << "Hello World!\n";

    for(size_t i = 0 ; i < 4 ; i++)
    {
        testers.emplace_back(InnerHelloWorld);
    }

    sleep(1);

    return 0;
}

您的代码中存在一些小问题

你错过了以下的尾随分号:

th.join()

但重要的是,你需要给你的类一个移动构造函数 - 默认的是:

Tester(Tester&&) = default;

这是必需的,因为当向量调整大小时,他们需要移动或复制它们的元素。 通常会为您创建移动构造函数,但在您的情况下,使用自定义析构函数会对其进行压缩。 看到这里

这将让你的代码编译,但它会在运行时抛出异常。 这是因为你有时会从被移动的Testers中移除,这将调用从线程移动的连接。 幸运的是,这是一个简单的修复:

~Tester()
 {
   if(th.joinable())
       th.join();
 }

完整的工作代码:

#include <iostream>
#include <thread>
#include <vector>
#include <functional>

#include <unistd.h>

class Tester
{
  public:
  Tester(std::function<void(void)> func) : 
    th(func)
  {
  }

  ~Tester()
  {
    if(th.joinable())
        th.join();
  }

  Tester(Tester&&) = default;

  private:
  std::thread th;
};

std::vector<Tester> testers;

void InnerHelloWorld()
{
  std::cout << "Hello from the inner word!\n";
}

int main() {
  std::cout << "Hello World!\n";

  for(size_t i = 0 ; i < 4 ; i++)
  {
    testers.emplace_back(InnerHelloWorld);
  }

  sleep(1);

  return 0;
}

您需要定义移动构造函数的类,使其成为MoveInsertable和满足的要求emplace方法:

Tester(Tester && other) : 
    th(::std::move(other.th))
{
}

修复缺少移动构造函数后出现的另一个问题是尝试连接不能连接的线程,因为实际的线程可能已被移动到另一个对象中。 所以你需要添加一个相应的检查:

~Tester()
{
   if(th.joinable())
   {
       th.join();
   }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM