c++ 11中如何在Mac OS X上命名std::线程

How to name std::thread on Mac OS X in C++11?

本文关键字:std 线程 OS Mac c++      更新时间:2023-10-16

我想命名一个线程,但不幸的是,Mac上的pthread_setname_np()只在当前线程内工作。

然后我用以下构造函数对std::thread进行包装:

template <class F, class ... Args>
Thread::Thread(const char* name, F&& f, Args&&... args) {
  thread_ = std::thread([name, f, args...]() {
    pthread_setname_np(name);
    f(args...);
  });
}

但是它不适用于类方法:

error: called object type '<complex type>' is not a function or function pointer
f(args...);
^

代码如下:

threads_.emplace_back("Name", &Aggregator<T>::DoPop, this, some_arg);

如何包装std::thread并设置线程名称,在构造函数中保留除name参数外的整个接口?

可以使用std::mem_fn调用成员函数。args中的第一个实参必须是指向成员对象的指针。

的例子:

#include <thread>
#include <functional>
template <class F, class ... Args>
std::thread thread_factory(const char* name, F&& f, Args&&... args) {
  return std::thread([=]{
    pthread_setname_np(name);
    auto fun = std::mem_fn(f);
    fun(args...);
  });
}
struct test {
  int t(int val) {
    return val;
  }
};
int main() {
  test t;
  auto b = thread_factory("name", &test::t, &t, 5);
  b.join();
}

必须将成员函数绑定到类实例。下面是您的函数,与(工作)测试略有不同:

#include <iostream>
#include <thread>
template <class F, class ... Args>
std::thread launch_named_thread(const char* name, F&& f, Args&&... args) {
    return std::thread([name, f, args...]() {
        pthread_setname_np(name);
        f(args...);
    });
}
struct myclass
{
    void thread_loop(int i)
    {
        std::cout << i << std::endl;
    }
};
auto main() -> int
{
    myclass x;
    auto t = launch_named_thread("hello", std::bind(&myclass::thread_loop, &x, 6));
    // this could be:
    // auto t = launch_named_thread("hello", std::bind(&myclass::thread_loop, &x, std::placeholders::_1), 6);
    // the difference is subtle. i'll leave it to you to work out why
    t.join();
    return 0;
}