【问题标题】:Filling a vector of unique_ptr with multiple threads?用多个线程填充 unique_ptr 的向量?
【发布时间】:2018-10-10 05:59:32
【问题描述】:

我有一个类,给定设备 ID,初始化该设备。类的析构函数再次对设备进行后台处理。

由于我有多个这样的设备连接到我的系统,我编写了一个枚举器类来初始化每个连接的设备。由于device的析构函数释放了设备的资源,所以我使用了unique_ptr< device >所以不会无意复制/删除device对象。

struct device_id {
    // information to identify device
}

class device {
    public:
        device( device_id const & id ) {
            // initialize device
        }

        void act() {
            // use the device
        }

        ~device() {
            // spool down device
        }
};

class device_enumerator {
    public:
        device_enumerator( std::vector< device_id > const & ids ) {
            for ( auto const & id : ids ) {
                devices.push_back( std::unique_ptr< device >( new device( id ) ) );
            }
        }

        typedef std::vector< std::unique_ptr< device > > device_vector;

        device_vector::iterator begin() { return devices.begin(); }
        device_vector::iterator end() { return devices.end(); }

    private:
        device_vector devices;
};

由于每个设备都需要一些时间来后台处理,因此按顺序初始化所有设备是一个漫长的过程。所以我想并行化设备初始化(因为设备构造函数基本上处于空闲状态,直到设备返回信号)。

但是 -- 这是我第一次尝试使用 &lt;thread&gt; -- 我无法理解如何从每个设备的 std::thread 中检索 std::unique_ptr&lt; device &gt;,然后加入再次线程,具有任何优雅。 (如果std::thread 确实是在这里使用的正确东西......)

我怎样才能并行化:

for ( auto const & id : ids ) {
    devices.push_back( std::unique_ptr< device >( new device( id ) ) );
}

【问题讨论】:

  • 移动分配可能比推回更容易,因为您将无需同步向量的并发修改。通过分配,就像#pragma omp parallel for 一样简单。

标签: c++ multithreading unique-ptr


【解决方案1】:

由于初始化每个设备是独立的任务,所以 std::async 在这里更有意义,实现这一点的示例代码如下:

void init(std::unique_ptr<device>& p)
{
  p.reset(new device(device_id())); //time consuming operation

}
int main() {
  //8 number of elements in vector are for demo purpose only
  std::vector<std::unique_ptr<device>> vecOfDevices(8); 
  std::vector<std::future<void>> vecOfFutures(8);
  int index = 0;
  for(auto& elem:vecOfDevices)
  {
    //async launch policy will construct each in seperate thread
    vecOfFutures[index] = std::async(std::launch::async,init,std::ref(vecOfDevices[index]));
    index++;
  }
  //Do some other operations here
  for(auto& elem:vecOfFutures)
  {
    elem.wait(); //wait so that all devices got initialized
  }
  //start using your devices from here
  vecOfDevices[0]->act();  
  return 0;
}

【讨论】:

    猜你喜欢
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多