如何在C++中获得线程ID?

885 阅读2分钟

在知道如何获得一个线程的id之前,你必须首先知道C++中线程id的两种形式。这相当于知道当线程没有运行时获得什么id,以及当线程运行时获得什么id。运行意味着执行。ID(代表IDentifier)是识别事物的东西。在C++中,线程ID的名称是id,小写的。

对于C++中的线程,id是一个具有数据成员和成员函数的对象。这个id对象有一个文本代码,这就是人们通常认为的id。id对象使用<<操作符,将文本代码发送到cout对象(终端)。从线程未运行时到运行时,id对象及其文本代码是不同的。

线程是一个类,其中id对象是一个数据成员。id对象可以通过以下语法获得。

    thread::get_id()

语法 "thread::get_id() "可以在线程未运行时使用,也可以在线程运行时使用,它将为两种不同的情况提供不同的对象和相应的文本代码。

在线程运行时,在线程体中获取线程ID的方法是使用语法。

    this_thread::get_id()

所有正在运行的线程都有不同的id对象和相应的文本代码。所有未运行的线程对于同一个程序都有相同的对应文本代码。虽然它们有相同的文本代码,但所有未运行的线程都有不同的id对象,因为对象是引用而不是指针。

一个正在运行的线程被称为执行线程。

要编译一个线程的程序,用g++编译器,使用类似的命令。

  g++ -std=c++2a temp.cpp -lpthread -o temp

这篇文章解释了在C++中获得不同线程ID的不同方法,首先是对什么是线程的总结。

文章内容

线程总结

一个线程是一个顶层函数的外壳。一个线程是由线程类实例化的。顶层函数的名称是线程对象构造函数的一个参数。C++中的main()函数也是一个顶层函数。所以main()函数的行为就像主线程。下面的程序显示了两个线程,main()函数是其中之一。

 #include <iostream>

    #include <thread>

    using namespace std;


    thread thr;


    void fun() {

        cout <<"This is line A." <<endl;

        cout <<"This is line B." <<endl;

    }


    int main()

    {

        thr = thread(fun);

        thr.join();


        /* statements */


        return 0;

    }

输出结果是:

 This is line A.

 This is line B.

顶层函数是fun()和main()。main()就像主线程。顶层函数的名称fun()是主函数中线程构造器three的参数。

程序开始时包含了iostream库。接着是加入线程库。之后的语句确保程序中使用的任何名称都是标准名称空间的,除非另有说明。

接下来,线程库被声明为没有函数调用。然后定义了顶层函数fun()。此后是main()函数的定义。main()中的第一条语句将函数fun()分配给线程thr,并调用该函数。

main()中的第二条语句是连接语句。如果没有这条语句,主线程可能会在没有线程thr运行完成的情况下运行完成。有了这个语句,在该语句被输入的地方,主线程(函数)停止(阻塞),并允许加入的线程(thr)执行完成;然后主线程继续完成自己的任务。试图在没有连接语句的情况下编译程序,最终会出现错误信息,无法编译。

当用语句声明线程时。

    thread thr;

时,它不是一个正在运行的线程;没有函数在运行。然而,当线程thr被赋予一个函数名作为参数时,如:。

thr\=thread(fun);

它就成了一个运行的线程。这条语句也是一个函数调用,用于函数fun()。

在主函数的连接语句之后,线程thr已经完成了它的执行,它不再是一个正在运行的线程。在这种状态下,它的id与运行时的id是不同的。

获取线程id

下面的程序显示了当线程不执行时和执行时获取线程id的基本方法。

 #include <iostream>

    #include <thread>

    using namespace std;


    thread thr;


    void fun() {

        cout <<"This is line A." <<endl;

        thread::id idR = thr.get_id();

        cout <<idR <<endl;

        cout <<"This is line B." <<endl;

    }


    int main()

    {

        thread::id idD = thr.get_id();

        cout <<idD <<endl; cout <<endl;

        thr = thread(fun);

        thr.join();

        //cout <<thr.get_id() <<endl;


        /* statements */


        return 0;

    }

笔者电脑的输出是:

thread::id of a non-executing thread


    This is line A.

    140362842543872

    This is line B.

thr是一个全局变量。它被用于线程three的函数体中,在语句中。

    thread::id idR = thr.get_id();

保存获得的线程对象的变量是idR。尽管id是一个实例化的对象,但它也是线程类的一个成员。所以idR的声明必须是。

    thread::id idR

并加上分号。这条语句之后的下一条语句是。

        cout <<idD <<endl;

操作符,<<获得并插入文本版本的id到cout(终端)。注意:这种情况下的id是在线程运行(执行)时获得的。在线程不执行时获得id的语句是

     thread::id idD = thr.get_id();

在main()函数中。它与线程执行函数中的语句相同,只是接收变量idD不同。这条语句是在线程,thr被分配到一个函数之前执行的。这个没有执行的线程的文本id(代码)是。

    thread::id of a non-executing thread

在main()函数的执行过程中,线程thr在join语句之后已经完成了自己的执行。于是,"thr.get_id() "应该能够返回该线程不执行时的id。从目前来看,用g++编译的C++程序很难获得已经运行完成的线程的id。这就是为什么上面的代码中join语句后的id语句被注释掉了。

使用this_thread::get_id()

"this_thread:: "是在执行的线程(函数)内编码的。它代表当前正在运行的线程。它后面可以跟一个线程的函数,比如get_id(),以使

 this_thread::get_id()

来获得正在运行的线程的id,这个id与线程不运行时的id不同。

"this_thread:: "是在线程的函数体内使用。下面的程序为线程说明了这一点,three。

 #include <iostream>

    #include <thread>

    using namespace std;


    thread thr;


    void fun() {

        cout <<"This is line A." <<endl;

        thread::id idR = this_thread::get_id();

        cout <<idR <<endl;

        cout <<"This is line B." <<endl;

    }


    int main()

    {

        thread::id idD = thr.get_id();

        cout <<idD <<endl; cout <<endl;

        thr = thread(fun);

        thr.join();


        return 0;

    }

作者电脑的输出结果是:

thread::id of a non-executing thread


    This is line A.

    140199206078208

    This is line B.

请注意,在这种情况下,线程名称three并没有在线程函数体内使用。

结论

C++中的线程ID有两种形式。线程执行时的ID与线程不执行时的ID不同。ID(即IDentifier)是识别事物的标志。在C++中,线程ID的名字是id,小写的。这是线程类中的一个数据成员。它不是一个基本对象。它是从自己的类中实例化出来的,属于命名空间,即thread::id。虽然id是一个对象,但它有一个相应的文本形式。该文本形式可以用C++的插入操作符<<插入到cout对象(终端)中。

每个线程有两个不同的ID。一个是当线程正在运行时;另一个是当线程没有运行时。当线程不运行时,ID的文本形式与同一线程运行时的文本形式不同。

C++规范中有多种获取线程ID的方法。然而,截至目前,在g++编译器中,获取id的唯一方法是来自表达式。"threadObject.get_id() "和 "this_thread::get_id()"。"this_thread::get_id() "在执行线程的函数体内使用,其中 "this_thread:: "指的是当前运行的线程。一个正在运行的线程被称为执行线程。