【问题标题】:How can I use boost::thread::id as key to an unordered_map?如何使用 boost::thread::id 作为 unordered_map 的键?
【发布时间】:2010-05-17 15:01:46
【问题描述】:

根据documentation,可以认为boost::thread::id对于每个正在运行的线程都是唯一的,并且可以在std::setstd::map等容器中使用(因为<运算符被thread::id覆盖)。

我的问题是我想使用thread::id 作为boost::unordered_map 的密钥,但是它要求密钥是“可散列的”(即支持散列到size_t)。由于 thread::id 的所有实现细节都被隐藏了,我认为没有什么可以使用的。

所以我的问题是 - 是否可以使用 thread::id 作为 unordered_map 的键?

【问题讨论】:

标签: c++ boost multithreading unordered-map


【解决方案1】:

您可以使用流媒体功能:

struct Hasher
{
  size_t operator()(const boost::thread::id& id)
  {
    std::ostringstream os; os << id; return hash(os.str());
  }
};

类的一小部分摘录,以便其他人可以看到什么是可能的:

class thread::id
{
public:
    id();

    bool operator==(const id& y) const;
    bool operator!=(const id& y) const;
    bool operator<(const id& y) const;
    bool operator>(const id& y) const;
    bool operator<=(const id& y) const;
    bool operator>=(const id& y) const;

    template<class charT, class traits>
    friend std::basic_ostream<charT, traits>& 
    operator<<(std::basic_ostream<charT, traits>& os, const id& x);
};

【讨论】:

    【解决方案2】:

    你有多少线程?除非你有数百个,否则不太可能 unordered_map 带有重散列(并且散列很重,尤其是基于 std::stringstream)会比 std::map 更快。不要伪造std::map 的日志复杂性和非常小的常数。

    如果您有数百个线程,那么您的应用程序可能存在问题。

    【讨论】:

      【解决方案3】:

      为什么需要继续处理字符串?你可以使用

      size_t operator()(const boost::thread::id& id)
      {   
          using boost::hash_value;
      
          return hash_value(id);
      }
      

      【讨论】:

      • 当时我认为 hash_value 没有实现(2010),但现在这是正确的答案。
      【解决方案4】:

      文档说它可以写入流。将其写入std::ostringstream 并散列str() 结果。尽管未指定输出格式,但它对于给定的 ID 是唯一的,并且对于给定的程序运行是一致的(只要线程 ID 仍然有效)。

      【讨论】:

      • 我不太确定线程 ID。我正在开发 Linux (gcc) 上的多线程应用程序,并且由于我们创建线程的顺序从一次运行到另一次运行是一致的,因此它们始终具有相同的 id。它实际上是用来使“应用”线程的 ID 为 13 in gdb
      • 我认为依靠它并不安全。
      猜你喜欢
      • 2012-10-07
      • 2013-05-04
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      相关资源
      最近更新 更多