2.5标识线程

标识线程

线程标识符是 std::thread::id 类型的,并且有两种获取方式。其一,线程的标识符可以通过从与之相关联的std::thread对象中通过调用get_id()成员函数来获得。如果std::thread对象没有相关联的执行线程,对get_id()的调用返回一个默认构造的std::thread::id对象,表示“没有线程”。另外,当前线程的标识符,可以通过调用std::this_thread::get_id()获得,这也是定义在<thread>头文件中的。

std::thread::id类型的对象可以自由地复制和比较;否则,它们作为标识符就没什么大用处。如果两个std::thread::id类型的对象相等,则它们代表着同一个线程,或两者都具有“没有线程”的值。如果两个对象不相等,则它们代表着不同的线程,或其中一个代表着线程,而另一个具有“没有线程”的值。

线程库不限制你检查线程的标识符是否相同,std::thread::id类型的对象提供了一套完整的比较运算符,提供了所有不同值的总排序。这就允许它们在关系型容器中被用作主键,或是被排序,或者任何作为程序员的你认为合适的方式进行比较。比较运算符为std::thread::id 所有不相等的值提供了一个总的排序,所以它们表现为你直觉上期望的那样:如果a<b且 b<c,那么a<c,等等。标准库还提供了std::hash<std::thread::id>,使得std::thread::id类型的值可在新的无序关系型容器中作为主键来用。

std::thread::id的实例常被用来检查一个线程是否需要执行某些操作。例如,如果线程像在清单2.8中那样的被用来分配工作,启动了其他线程的初始线程在需要做的工作可能会在算法中略有不同。在这种情况下,它可以在启动其他线程之前存储std::this_thread::get_id()的结果,然后算法的核心部分(这对所有线程都是公共的)可以对照所存储的值来检查自己的线程ID。

std::thread::id master_thread;
void some_core_part_of_algorithm()
{
    
    
     if(std::this_thread::get_id()==master_thread)
     {
    
    
          do_master_thread_work();
     }
     do_common_work();
}

另外,当前线程的std::thread::id可以作为操作的一部分而存储在数据结构中。以后在相同数据结构上的操作可以对照执行此操作的线程ID来检查所存储的ID,来确定哪些操作是允许的/需要的。

类似地,线程ID可以指定的数据需要与一个线程进行关联,并且诸如线程局部存储这样的替代机制不适用的地方,用作关系型容器的主键。例如这样的一个容器,它可以被控制线程用来存储关于在它控制下的每个线程的信息,或是在线程之间传递信息。

这种想法就是,在大多数情况下,std::thread::id足以作为线程的通用标识符。只有当标识符具有与其相关联的语义(比如作为数组的索引)时,才有必要用替代方案。你甚至可以将一个std::thread::id实例写到诸如std::cout这样的输出流中。

std::cout << std::this_thread::get_id();

你得到的确切的输出,严格取决于实现;标准给定的唯一保证是,比较结果相等的线程ID应该产生相同的输出,而那些比较结果不相等的应该给出不同的输出。因此,这主要是对调试和日志有用,但数值是没有语义的,所以也没有更多可说的了。

Guess you like

Origin blog.csdn.net/qq_36314864/article/details/132090074