C++ 便携式打印和比较pthread\u t

C++ 便携式打印和比较pthread\u t,c++,multithreading,posix,portability,C++,Multithreading,Posix,Portability,我实际上需要的是*nix pthread标识符(pthread_t)的可移植比较和打印。 pthread_equal函数用于比较两个线程id是否相等,但是无法将它们与运算符(当然是可移植的),因为在某些实现中pthread_t是指向结构的指针。所以我找到了一个解决方案,我想和大家分享并讨论它的可移植性 假设我们有一个thred_id类包装器,它应该是可比较的、相等的,当然是可打印的。我正在使用两个部分专门化来创建模板类——一个用于指针,另一个用于算术类型 template <typenam

我实际上需要的是*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);
    }
};
但是对于运算符<,我们使用哈希进行比较

hash<pthread_t>::calculate(tid1) < hash<pthread_t>::calculate(tid2)
hash::calculate(tid1)
所以这里

如果
pthread\u t
被实现为指针,那么我们将计算指向对象的哈希值

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

如果它被实现为一个结构-我们将计算结构对象本身的哈希值

哈希值将仅用于无运算符和线程id输出

你觉得怎么样?这个解决方案的可移植性如何?还有比它更好的吗


提前感谢大家。

您不必尝试比较
pthread\t
而只需封装线程创建并将新线程添加到
映射中,在该映射中生成唯一的id。然后您总是按id引用线程,您可以随意对它们进行排序、排序和比较。

pthread\u t的数据类型不是标准固定的,因此我猜提供了
pthread\u compare()

在我的应用程序中,我还将pthread\u t映射到某个唯一的id,正如Mark所建议的那样


参见

pthread\t也不一定是标量数据类型,标准规定它应该是不透明类型,可以是结构、联合或位字段

除此之外,pthread_t(包括标量pthread_t)可能包含填充位,这些填充位将引入影响哈希结果的“噪声”。目前还没有通用的可移植方法在用户级别比较pthread\u t

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


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

实际上我不需要将线程存储在容器中,我需要ti write thread_id包装器,它可以存储在关联容器中,进行比较和打印。当然,我可以在线程创建上设置处理程序并将id存储在一些全局映射中,但这不是我正在寻找的解决方案,在大多数情况下,pthread_t是一个艺术计算值,它唯一地代表系统中的线程,我不想使用代理id。我知道它不是固定的。这就是我想解决的问题。没有函数pthread_compare,只有pthread_equal,它只检查两个线程id的相等性。我要说的是与less操作符(操作符)相比,为什么要对固有的无序类型强制执行一个命令?从概念上讲,您试图实现什么?
hash<pthread_t>::calculate(tid1) < hash<pthread_t>::calculate(tid2)