C ++ 11'native_handle'不是'std :: this_thread'的成员

时间:2013-04-28 03:22:30

标签: c++ c++11 stdthread

在以下代码段中,

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

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

  t1.join();
  return 0;
}

如何从native_handle函数中获取std::this_thread的{​​{1}}?

5 个答案:

答案 0 :(得分:12)

线程无法自主获取对自己std::thread的访问权限。这是有目的的,因为std::thread是一种仅移动类型。

我相信您要求的是native_handle()成员std::thread::id,这是一个有趣的建议。据我所知,目前还不可能。它将被用作:

void foo()
{
    auto native_me = std::this_thread::get_id().native_handle();
    // ...
}

不能保证工作,甚至不存在。但是我想大多数POSIX平台都可以支持它。

尝试更改C ++标准的一种方法是提交问题。 Here是有关如何操作的说明。

答案 1 :(得分:5)

C ++ 11没有提供获取当前线程native_handle的机制。您必须使用特定于平台的调用,即Windows上的GetCurrentThread():

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

答案 2 :(得分:2)

正如Howard指出的那样,ISO C ++中还没有支持这一点。

thread::id ostream的{​​{1}}到打印本身已超负荷。

#include <iostream>
#include <thread>

int main()
{
    std::cout << "Current thread ID: " << std::this_thread::get_id() << std::endl;
}

在不知道实际值的语义(高度依赖于平台)的情况下,打印它或将其用作地图中的关键字是你应该做的最多。

答案 3 :(得分:0)

当前(C ++ 17)您无法从native_handle获得std::this_thread

最可能的界面可能是std::this_thread::native_handle()。但不是@Howardstd::this_thread::get_id().native_handle();

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

  • 在Linux上native_handle存储在线程中。 _M_id(类型为id) ._ M_thread。
  • 在Windows上,native_handle存储在thread._Thr(类型为_Thrd_t,而不是id类型)。_Hnd。
  • 在MacOS上,native_handle存储在线程中。__t _。

仅在Linux源代码中可以看到,native_hanlde对象以thread::id结构实现。因此,在Win / MacOS上,您无法从native_handle对象获得id

最后,如果您的代码仅在Linux上运行,则有一个肮脏的技巧可以从native_handle获取this_thread,我永远不会推荐:

auto thread_id = std::this_thread::get_id();
auto native_handle = *reinterpret_cast<std::thread::native_handle_type*>(&thread_id);

答案 4 :(得分:0)

事实上,有一种有趣的方法可以绕过这个问题并通过 std::thread 访问它,这在某些情况下可能有效。 原始示例发布在此 blog 上。我重写了它。 您可以将下面的代码保存到 test.cpp 并编译和运行它 :

// 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;
}