2015-08-08 61 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; 
}