代码之家  ›  专栏  ›  技术社区  ›  Naomi

将可变模板传递给pthread\u create

  •  0
  • Naomi  · 技术社区  · 7 年前

    我明白 pthread_create 接受 void*(*)(void*) 论元与a 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:在结构的实例化中 标准::绑定\u简单(标准::占位符<1>,int))(int*)>>()>: /usr/include/c++/4.8.2版本/future:1284:55:无效时需要 标准::\未来\基础::\任务\状态<_Fn,\u Alloc,\u Res(\u Args) …)>::_M_run(_Args…)[带_Fn=std::_Bind(std::_Placeholder<1>,int))(int*)>_Alloc=std::分配器; _Res=无效_Args={}]线程。cpp:17:1:此处需要/usr/include/c++/4.8.2/functional:1697:61:错误:没有名为type的类型 类内std::结果(std::占位符<1>,int))(int*)>>()&燃气轮机; ^/usr/include/c++/4.8.2/functional:1727:9:错误:没有名为type的类型 _M\u invoke(\u Index\u tuple<_索引…>) ^

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

    本应在叮当声中工作,但在GCC 4.8.5中失败:

    在线程包含的文件中。cpp:2:0: thread.h:在lambda函数中: thread.h:82:37:错误:参数 auto l=new auto([=]{callable(args…);}); ^螺纹h:82:37:注:
    args线程。h:82:41:错误: 扩展模式参数不包含参数包 auto l=new auto([=]{callable(args…);}); struct thread::线程(大小、可调用和&,参数(&A)&…)[具有 )(内景) ); Args={int*};size\u t=长无符号 int]::uu lambda4:线程。h:82:48:
    thread::thread(size\u t,Callable&&,参数(&A)&…) [带Callable=void( )(内景) [int]线程。cpp:14:32:此处需要 无效的字段thread::thread(size\u t,Callable&&,参数(&A)& …)::\u lambda4::\u args ^thread.h:83:被前面的搞糊涂了 错误,退出

    两者都有以下主要特点:

    int g=5;
    
    void run(int *i)
    {
        printf("t\n");
    }
    
    int main()
    {
    
        gs_thread t(256*1024, &run, &g);
        printf("m\n");
        t.join();
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Maxim Egorushkin    7 年前

    如果你移除 std::placeholders::_1, 从第一个版本开始,它使用gcc进行编译。