C++ C++;11';本机手柄';不是';std::此螺纹';

C++ C++;11';本机手柄';不是';std::此螺纹';,c++,c++11,stdthread,C++,C++11,Stdthread,在下面的代码段中 void foo() { std::this_thread::native_handle().... //error here } int main() { std::thread t1(foo); t1.join(); return 0; } 如何从函数foo内的std::this\u thread获取native\u句柄?线程无法自动访问自己的std::thread。这是故意的,因为std::thread是只移动的类型 我相信您所请求的是std::th

在下面的代码段中

void foo() {
  std::this_thread::native_handle().... //error here
}

int main() {
  std::thread t1(foo);

  t1.join();
  return 0;
}

如何从函数
foo
内的
std::this\u thread
获取
native\u句柄?

线程无法自动访问自己的
std::thread
。这是故意的,因为
std::thread
是只移动的类型

我相信您所请求的是
std::thread::id
native\u handle()
成员,这是一个有趣的建议。据我所知,目前还不可能。它的使用方式如下:

void foo()
{
    auto native_me = std::this_thread::get_id().native_handle();
    // ...
}
它不能保证工作,甚至不存在。然而,我认为大多数POSIX平台都可以支持它


P> >尝试改变C++标准的一种方法是提交问题。C++11没有提供获取当前线程本机句柄的机制。您必须使用特定于平台的调用,即Windows上的GetCurrentThread():

void foo()
{
    auto native_me = ::GetCurrentThread();
}

正如霍华德指出的,在ISOC++中没有支持。

但是
thread::id
有一个重载toprint自身到
ostream

#include <iostream>
#include <thread>

int main()
{
    std::cout << "Current thread ID: " << std::this_thread::get_id() << std::endl;
}
#包括
#包括
int main()
{
std::cout当前(C++17)无法从
std::this_线程

最可能的接口可能是
std::this_thread::native_handle()
。但不是
std::this_thread::get_id().native_handle();
by

由于Win/Linux/MacOS以不同的方式实现
thread
thread::id
(下面是非正式的伪代码)

  • 在Linux上,本机句柄
存储在线程中。\u M\u id(id类型)\u线程
  • 在Windows上,本机句柄存储在线程中。\u Thr(类型为\u Thrd\t,而不是类型id)。\u Hnd
  • 在MacOS上,本机句柄存储在线程中
  • 正如您只能在Linux源代码中看到的那样,在
    thread::id
    结构中实现了
    native\u hanlde
    对象。因此,在Win/MacOS上,您无法从
    id
    对象获取
    native\u句柄

    最后,如果您的代码仅在Linux中运行,那么从
    此线程
    获取
    本机句柄
    有一个肮脏的技巧,我永远不会推荐:

    auto thread_id = std::this_thread::get_id();
    auto native_handle = *reinterpret_cast<std::thread::native_handle_type*>(&thread_id);
    
    auto-thread_-id=std::this_-thread::get_-id();
    自动本机线程句柄=*重新解释线程类型(&thread);
    
    事实上,有一种有趣的方法可以绕过这个问题,并通过std::thread访问它,这种方法在某些情况下可能有效。 原来的例子贴在上面,我重写了。 您可以将下面的代码保存到test.cpp并编译和运行它 :

    //g++./test.cpp-lpthread&&./a.out
    // 
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    int main(int argc,常量字符**argv){
    constexpr unsigned num_threads=4;
    //互斥锁确保从多个线程有序地访问std::cout。
    std::互斥iomutex;
    std::向量线程(num_线程);
    for(无符号i=0;istd::cerr你认为像这样的东西值得作为C++14的提案提交吗?@NicholasPezolano:目前没有。但是我可以被一个激励性的用例和一个演示它的实现说服。也就是说,我认为我知道成本/风险。但我不认为我知道好处。如果好处是零,那么无论成本有多低t、 收益/成本比率很低。因此您需要展示一个很大的收益。我认为OP不一定需要
    std::thread::id::native\u handle
    。我认为有趣的一点是:
    std::this\u thread
    的接口不应该模仿
    std::thread
    的接口吗?当然,除了那些与线程生命周期管理,正如你正确地指出的那样,没有太多意义。这没有留下太多,但是
    native\u handle
    让我觉得明显不存在。@NicholasPezolano:可能吧,不要低估自己。我的观点是,向委员会出售一些东西,有助于他们了解为什么需要一些东西。d如果你只是说:我们为什么不这样做呢?我个人从来没有做过跨平台的线程分析器/调试器。所以我不知道这将如何大大简化事情。但我发现我自己希望自己知道。一篇由你自己撰写的更详细解释事情的论文可能会激励委员会。也可能不会。事实并非如此很难预测未来。为什么不
    std::this\u thread::native\u handle()
    ,就像
    get\u id()
    一样?这可以被视为“完成”-这两件事在所有线程系统中都可用,两件事在逻辑上都是一样的。如果
    this\u thread::native\u handle()有问题
    ,关于
    std::thread::native\u handle()
    也可以这么说。你需要激励性的用例吗?想想调试。Gdb不会向你显示由
    this\u thread::get\u ID()
    返回的ID为的线程列表。我不能投票支持我自己的帖子,但当我再次遇到这个问题并看到这个答案时,我大笑起来!
    // g++ ./test.cpp  -lpthread && ./a.out
    // 
    #include <thread>
    #include <vector>
    #include <iostream>
    #include <mutex>
    #include <sched.h>
    #include <pthread.h>
    int main(int argc, const char** argv) {
      constexpr unsigned num_threads = 4;
      // A mutex ensures orderly access to std::cout from multiple threads.
      std::mutex iomutex;
      std::vector<std::thread> threads(num_threads);
      for (unsigned i = 0; i < num_threads; ++i) {
        threads[i] = std::thread([&iomutex, i,&threads] {
          // Create a cpu_set_t object representing a set of CPUs. Clear it and mark
          // only CPU i as set.
          cpu_set_t cpuset;
          CPU_ZERO(&cpuset);
          CPU_SET(i, &cpuset);
          int rc = pthread_setaffinity_np(threads[i].native_handle(),
                                          sizeof(cpu_set_t), &cpuset);
          if (rc != 0) {
            std::cerr << "Error calling pthread_setaffinity_np: " << rc << "\n";
          }
          std::this_thread::sleep_for(std::chrono::milliseconds(20));
          while (1) {
            {
              // Use a lexical scope and lock_guard to safely lock the mutex only
              // for the duration of std::cout usage.
              std::lock_guard<std::mutex> iolock(iomutex);
              std::cout << "Thread #" << i << ": on CPU " << sched_getcpu() << "\n";
            }
    
            // Simulate important work done by the tread by sleeping for a bit...
            std::this_thread::sleep_for(std::chrono::milliseconds(900));
          }
        });
    
    
      }
    
      for (auto& t : threads) {
        t.join();
      }
      return 0;
    }