2011-01-21 97 views
1

我真正需要的是便携式比较和打印* nix pthread标识符(pthread_t)。 pthread_equal函数存在比较两个线程ID的相等性,但它不可能与运算符< < => =>(可移植我的意思当然),因为在某些实现pthread_t是一个指向结构的指针。所以我找到了我想分享和讨论它的便携性的解决方案。便携式打印和比较pthread_t

假设我们有thred_id类包装器,它应该少于可比,平等可比,当然可打印。我在做模板类有两个偏特 - 一个指针和一个算术类型

template <typename T, bool A = is_arithmetic<T>::value> 
struct hash 
{ 
    static unsigned long calculate(T thread_id) 
    { 
     return hash<T*, A>::calculate(&thread_id); 
    } 
}; 

template <typename T> 
struct hash<T*, false> 
{ 
    static unsigned long calculate(T* thread_id) 
    { 
     std::size_t hash = 0; 
     if (char* data = reinterpret_cast<char*>(thread_id)) 
     { 
      for (int i = 0; i < sizeof(T); ++i) 
      { 
       hash = (hash << 6)^(hash >> 26)^data[i]; 
      } 
     } 
     return hash; 
    } 
}; 

template <typename T> 
struct hash<T, true> 
{ 
    static unsigned long calculate(T thread_id) 
    { 
     return static_cast<unsigned long>(thread_id); 
    } 
}; 

那么它是怎样工作的。如果我们需要比较两个线程ID,我们只是简单地调用

pthread_equal(tid1, tid2); 

但对于运营商<我们使用哈希比较

hash<pthread_t>::calculate(tid1) < hash<pthread_t>::calculate(tid2) 

所以这里

如果pthread_t作为指针实现,那么我们将为指出的对象计算散列值。

如果是算术类型,那么我们将尝试将其转换为无符号整型。

如果它是作为结构实现的 - 我们将计算结构对象本身的哈希值。

哈希值将仅用于运算符较少和线程ID输出。

您对此有何看法?这种解决方案的便携性如何,还有什么更好的呢?

谢谢大家。

+0

为什么你想强制执行一个固有的无法编辑的命令?你试图完成什么概念? – FooF 2013-07-12 04:53:19

回答

1

而不是试图比较pthread_t你可以封装线程创建,并将新线程添加到一个map<some_id, pthread_t>其中id是生成和唯一的。然后你总是通过id引用线程,你可以对它们进行排序,排序,然后根据你的喜好进行比较。的pthread_t的

+0

其实我不需要在一个容器中存储线程,我需要ti写入thread_id包装,它可以存储在关联容器中,进行比较和打印。当然,我可以在线程创建时设置处理程序,并将其存储在某个全局映射中,但这不是我正在寻找的解决方案,在大多数情况下,pthread_t是唯一表示系统中线程的artithmetical值,我不喜欢使用代理ID。 – axe 2011-01-21 18:51:30

0

数据类型不是通过标准的固定,threfore我想提供pthread_compare()

在我的应用程序中,我还将pthread_t映射到某个唯一的ID,如Mark所建议的那样。

here

+1

我知道它不是固定的。这是我正在努力解决的。没有函数pthread_compare,有pthread_equal,它只检查两个线程ID是否相等。我在说的是与POSIX不提供的运算符(运算符<)相比较少,所以我试图做一些。 – axe 2011-01-22 08:33:26

1

的pthread_t也未必是标量数据类型,标准说,这应该是一个不透明的类型,它可能是一个结构或联合或位字段。

除此之外,的pthread_t,包括标量的pthread_t,可以含有填充比特,将介绍的“噪声”影响散列结果。目前没有通用的便携方式来比较用户级别的pthread_t。

事实上,在系统pthread_equal其中的pthread_t是一个指针可以返回平等即使两个ARGS实际上是指不同的线程,例如一个线程可以退出和一个新的线程可以创建具有相同的指针值和由此的pthread_t值。

映射的唯一ID技术将工作,您不需要执行反向查找,因为映射可能是1:n。如果您连续退出并创建线程,地图也会变得非常大。