2015-08-08 155 views
1

我想命名一个线程,但不幸的是,Mac上的pthread_setname_np()只能在当前线程内工作。如何在C++ 11中的Mac OS X上命名std :: thread?

然后我周围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之外的整个接口?

回答

1

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

例子:

#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(); 
} 
+0

什么是要点?你的代码也不起作用。 –

+0

适合我,你编译器是什么? '苹果LLVM版本6.1.0(铛602.0.53)(基于LLVM 3.6.0svn)' – Hamdor

+0

版本是一样的 - 你有没有尝试过一些类的方法? –

1

你有你的成员函数绑定到一个类的实例。这里的功能与(工作)测试略有不同:

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