便携式打印并比较pthread_t

时间:2011-01-21 18:17:20

标签: c++ multithreading posix portability

我真正需要的是便携式比较和打印* nix pthread标识符(pthread_t)。 pthread_equal函数用于比较两个线程id的相等性,但是不可能将它们与运算符进行比较< < => => (我当然是可移植的)因为在某些实现中,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);

但对于运营商&lt;我们使用哈希来比较

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

所以这里

如果将pthread_t实现为指针,那么我们将计算指向对象的哈希值。

如果是算术类型,那么我们将尝试将其转换为unsigned int。

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

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

你怎么看?这个解决方案有多便携,那还有什么比这更好的了吗?

提前感谢大家。

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

pthread_t也不一定是标量数据类型,标准说它应该是一个opaque类型,它可以是struct或union或bit字段。

除此之外,pthread_t(包括标量pthread_t)可能包含填充位,这些位将引入影响散列结果的“噪声”。目前,没有普遍可移植的方法来比较用户级别的pthread_t。

实际上,pthread_t是指针的系统上的pthread_equal可以返回相等,即使两个args实际引用不同的线程,例如一个线程可以退出,并且可以创建一个具有相同指针值并因此具有pthread_t值的新线程。

映射的唯一ID技术将起作用,前提是您永远不需要进行反向查找,因为映射可能是1:n。如果你不断退出并创建线程,地图也会变得非常大。

答案 2 :(得分:0)

pthread_t的数据类型不是标准固定的,因此我想提供pthread_compare()

在我的appl中,我也将pthread_t映射到一些唯一的ID,就像马克提出的那样。

请参阅here