包含std :: threads的元素的向量

时间:2018-07-27 08:28:28

标签: c++ multithreading c++11

我有一个<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script type="text/javascript"> var app = angular.module("myApp", []); app.controller("myCtrl", function($scope) { $scope.alert = function($event) { if ($scope.currentElement) { alert($scope.currentElement.value); } } $scope.setFocus = function(event) { $scope.currentElement = event.target; } $scope.cancelFocus = function(event) { $scope.currentElement = false; } }); </script> </head> <body ng-app="myApp" ng-controller="myCtrl"> <div ng-init="names=['A', 'B', 'C']"> <select class="form-control input-sm" ng-model="fda" ng-change="alert()" ng-focus="setFocus($event)" ng-blur="cancelFocus($event)" ng-options="value for value in names"> </select> </div> </body> </html>类,其中包含一个Tester对象和一个std:thread中的一个std::vector。我知道我无法复制线程,所以Tester没问题,但是为什么push_back无法正常工作?我的代码中的副本在哪里?

emplace_back

2 个答案:

答案 0 :(得分:15)

您的代码中有几个小问题

您错过了结尾的分号:

th.join()

但是重要的是,您需要给您的类一个move构造函数-默认值是可以的:

Tester(Tester&&) = default;

这是必需的,因为当向量调整自身大小时,它们需要移动或复制其元素。通常会为您创建一个移动构造函数,但在您的情况下,使用自定义析构函数将阻止该构造函数。参见here

这将使您的代码编译,但随后它将在运行时引发异常。这是因为有时您会从Testers中移出,这会在线程移出时调用join。幸运的是,这很容易解决:

~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;
}

答案 1 :(得分:3)

您需要为您的类定义move构造函数,以使其变为 MoveInsertable 并满足emplace方法的要求:

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

一旦解决了缺少移动构造函数的问题,另一个问题是试图加入不是必须加入的线程,因为实际的线程可能已经移入了另一个对象。因此,您需要添加相应的检查:

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