c++ - 将可变参数模板传递给 pthread_create

标签 c++ multithreading c++11

我知道 pthread_create 接受一个 void*(*)(void*) 参数和一个 void*,所以我做了 2 (失败)尝试包装函数和参数...:

一个。创建一个 C 风格的 void *run(void*) 函数,它将调用传递给它的 std::function 对象:

class thread
{
public:
    typedef std::function<void()> functor_t;

    static void* run(void* f) 
    {
        functor_t* functor = (functor_t*)f;
        (*functor)();
        delete functor;
        return nullptr;
    }

    template<typename Callable, typename... Args>
    explicit thread(size_t stack_size, Callable && callable, Args&&... args) {
        auto task_ptr = std::make_shared<std::packaged_task<decltype(callable(args...))()>>(
            std::bind(std::forward<Callable>(callable), std::placeholders::_1, std::forward<Args>(args)...)
            );
        functor_t* functor = new functor_t([task_ptr]() {
            (*task_ptr)();
        });

        pthread_attr_t attr = { 0};
        if (pthread_attr_init(&attr) == 0)
        {
            m_joinable = pthread_attr_setstacksize(&attr, stack_size) == 0 &&
                         pthread_create(&m_id, &attr, &run, functor);
            pthread_attr_destroy(&attr);
        }
    }
private:
    pthread_t   m_id        = -1    ;
    bool        m_joinable  = false ;
};

这会导致 GCC 4.8.5 出现以下错误:

/usr/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple(std::_Placeholder<1>, int))(int*)> >()>’: /usr/include/c++/4.8.2/future:1284:55: required from ‘void std::__future_base::_Task_state<_Fn, _Alloc, _Res(_Args ...)>::_M_run(_Args ...) [with _Fn = std::_Bind(std::_Placeholder<1>, int))(int*)>; _Alloc = std::allocator; _Res = void; _Args = {}]’ thread.cpp:17:1: required from here /usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of(std::_Placeholder<1>, int))(int*)> >()>’ typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/include/c++/4.8.2/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of(std::_Placeholder<1>, int))(int*)> >()>’ _M_invoke(_Index_tuple<_Indices...>) ^

按照这个例子 http://coliru.stacked-crooked.com/a/a6c607514601b013

class thread
{
public:
    template< typename Callable, typename... Args >
    explicit thread(size_t stack_size, Callable&& callable, Args&&... args )
    {
        auto l = new auto([=]{ callable(args...); });
        auto te = [](void* rp) -> void*
        {
            auto p = reinterpret_cast<decltype(l)>(rp);
            (*p)();
            delete p;
            return nullptr;
        };
        pthread_attr_t attr = { 0};
        if (pthread_attr_init(&attr) == 0)
        {
            m_joinable = pthread_attr_setstacksize(&attr, stack_size) == 0 &&
                         pthread_create(&m_id, &attr, te, l);
            pthread_attr_destroy(&attr);
        }
    }
private:
    pthread_t   m_id        = -1    ;
    bool        m_joinable  = false ;
};

这应该在 clang 中工作,但在 GCC 4.8.5 中失败:

In file included from thread.cpp:2:0: thread.h: In lambda function: thread.h:82:37: error: parameter packs not expanded with ‘...’: auto l = new auto([=]{ callable(args...); }); ^ thread.h:82:37: note:
‘args’ thread.h:82:41: error: expansion pattern ‘args’ contains no argument packs auto l = new auto([=]{ callable(args...); }); ^ thread.h: In instantiation of ‘struct thread::thread(size_t, Callable&&, Args&& ...) [with Callable = void ()(int); Args = {int*}; size_t = long unsigned int]::__lambda4’: thread.h:82:48:
required from ‘thread::thread(size_t, Callable&&, Args&& ...) [with Callable = void ()(int); Args = {int*}; size_t = long unsigned int]’ thread.cpp:14:32: required from here thread.h:82:37: error: using invalid field ‘thread::thread(size_t, Callable&&, Args&& ...)::__lambda4::__args’ auto l = new auto([=]{ callable(args...); }); ^ thread.h:83: confused by earlier errors, bailing out

两者都与以下主程序一起运行:

int g=5;

void run(int *i)
{
    printf("t\n");
}

int main()
{

    gs_thread t(256*1024, &run, &g);
    printf("m\n");
    t.join();
}

最佳答案

如果您从第一个版本中删除 std::placeholders::_1,,它将使用 gcc 进行编译。

关于c++ - 将可变参数模板传递给 pthread_create,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52944309/

相关文章:

c++ - 为什么将 "score[11] = {};"和 "grade"声明为 "unsigned"而不是 "int'

C++ 添加 EXE 文件到 EXE 程序

在 JavaFX 应用程序线程以外的线程上进行 ImageIO 调用的 JavaFX 应用程序在 Mac OS X 上挂起

C++11 将多个共享指针存储为原始指针

java - 给线程的最小时间

ios - 如何计算 iOS 中的事件线程数

c++ - 为 iOS 编译 OpenFST 时出现转换错误

c++ - 双冒号前的 clang 格式中断

c++ - 为什么我的 double 在我将它们传递给 cout 时显示为整数?

c++ - 远程 GDB 调试