当前位置: 首页 > 知识库问答 >
问题:

将variadic模板传递给pthread_create

刘骏祥
2023-03-14

我知道pthread_create接受void*(*)(void*)参数和void*,所以我已经尝试了2次(失败)来包装函数和args...:

a.创建一个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:在'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_args={}]'thread.cpp:17:1:此处必需/usr/include/c++/4.8.2/function:1697:61:错误:在'class std::result_of(std::_placeholder<1>,int))(int*)>>()>'typedef typename result_of<_callable(_args...)>::type result_type;^/usr/include/c++/4.8.2:function:1727:9:错误:在'class_index_tuple<_indexes...>)^

b.以下为http://coliru.stacked-crooked.com/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中失败了,原因是:

infile from thread.cpp:2:0:thread.h:In lambda function:thread.h:82:37:error:参数包未用“...”展开:auto l=new auto([=]{callable(args...);});^thread.h:82:37:注意:
“args”thread.h:82:41:错误:扩展模式“args”不包含参数包auto l=new auto([=]{callable(args...);});^thread.h:在'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(thread_t,Callable&&,Args&&...)[with Callable=void()(int);Args={int*};size_t=long unsigned&&...)::__lambda4::__Args的auto l=新的auto([=]{Callable(Args...);});^thread.h:83:被以前的错误搞糊涂,退出

两人都跑了follwing Main:

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个答案

澹台博文
2023-03-14

如果从第一个版本中删除std::placeholders::_1,则将使用GCC编译。

 类似资料:
  • 问题内容: 尝试访问传递给模板的函数时出现错误: 有人可以让我知道我在做什么错吗? 模板文件(struct.tpl): 调用文件: 这是用于生成struct样板代码的程序(以防万一有人想知道为什么我要在模板中这样做)。 问题答案: 自定义函数需要在解析模板之前进行注册,否则解析器将无法分辨标识符是否为有效的函数名。模板被设计为可静态分析的,这是必需的。 您可以先使用创建一个新的未定义模板,并且除了

  • 如果ngFor循环使用带有then/else语法的模板,如何将ngFor循环中的当前变量传递给ngIf? 当内联使用时,它们似乎通过罚款,但不能从模板访问,例如: 模板似乎根本无法访问,但如果内联使用,它可以工作。 在下面的链接中有一个工作和不工作版本的完整例子

  • 问题内容: 我正在建立一个包括条目之间关系的通讯簿。我为个人,公司,场地和角色有单独的模型。在我的索引页面上,我想列出每个模型的所有实例,然后对其进行过滤。这样一个人可以轻松地搜索和查找条目。我已经能够使用通用视图列出单个模型,并使用get_extra_context显示另一个模型: 我还可以使用自定义视图列出单个模型: 这是这两个测试的urls.py: 所以我的问题是“如何修改此参数以将更多模型

  • 如果这个例子比较复杂,我很抱歉,但我希望它能帮助人们更好地理解现代C++用法。所以我想让这段代码工作起来。它应该为单积分型和变分型产生特殊的lambdas,以便在硬静态转换为单积分型或软变分转换为普通型时计算项的顺序。我添加了注释,这些注释描述了我在这段代码中真正尝试做的事情。

  • 问题内容: 我的Webapp导航系统中有一个表格,每次呈现页面时,该表格都会填充最新信息。如何避免在每个代码中放置以下代码? 用于填充表格。该表将显示在每个页面上 问题答案: 您可以使用Flask的上下文处理器将全局变量注入到Jinja模板中 这是一个例子: 为了将新变量自动注入模板的上下文中,Flask中存在上下文处理器。上下文处理器在呈现模板之前运行,并且能够将新值注入到模板上下文中。上下文处

  • 要解决的问题: 怎么创建一个拥有1个、2个或者更多的初始化器的类? 怎么避免创建一个实例而只拷贝部分的结果? 怎么创建一个元组? 最后的问题是关键所在:考虑一下元组!如果你能创建并且访问一般的元组,那么剩下的问题也将迎刃而解。 这里有一个例子(摘自“可变参数模板简述(A brief introduction to Variadic templates)”(参见参考)),要构建一个广义的、类型安全的