当前位置:  开发笔记 > 编程语言 > 正文

C++:使用packaged_task进行核心转储

如何解决《C++:使用packaged_task进行核心转储》经验,为你挑选了1个好方法。

我得到了一个奇怪的核心转储,我从http://en.cppreference.com/w/cpp/thread/packaged_task中的一部分代码中复制了这个转储,

#include 
#include 
#include 

void task_lambda() {
    std::packaged_task task([](int a, int b) {
        return std::pow(a, b);
    });
    std::future result = task.get_future();

    task(2, 9);

    std::cout << "task_lambda:\t" << result.get() << '\n';
}


int main() {
    task_lambda();
}

我懂了

terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
[1]    28373 abort (core dumped)  ./a.out

调用堆栈如下所示:

#0  0x00007ffff71a2428 in __GI_raise (sig=sig@entry=6) at              ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007ffff71a402a in __GI_abort () at abort.c:89
#2  0x00007ffff7ae484d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7ae26b6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7ae2701 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7ae2919 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7b0b7fe in std::__throw_system_error(int) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x0000000000404961 in std::call_once ()>*, bool*), std::__future_base::_State_baseV2*, std::function ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function ()>*&&, bool*&&) (__once=..., __f=)
at /usr/include/c++/5/mutex:746
#8  0x0000000000403eb2 in std::__future_base::_State_baseV2::_M_set_result(std::function ()>, bool) (
this=0x61ec30, __res=..., __ignore_failure=false) at /usr/include/c++/5/future:387
#9  0x0000000000402b76 in std::__future_base::_Task_state, std::allocator, int(int, int)>::_M_run(, ) (this=0x61ec30, __args#0=, 
__args#1=) at /usr/include/c++/5/future:1403
#10 0x00000000004051c1 in std::packaged_task::operator()(int, int) (this=0x7fffffffdca0, __args#0=2, __args#1=9) at /usr/include/c++/5/future:1547
#11 0x0000000000401c7d in task_lambda () at aa.cc:12
#12 0x0000000000401d1b in main () at aa.cc:19

然后我在程序中添加了一些示例代码,它就变成了

#include 
#include 
#include 
#include 
int f(int x, int y) { return std::pow(x,y); }
void task_thread() {
    std::packaged_task task(f);
    std::future result = task.get_future();

    std::thread task_td(std::move(task), 2, 10);
    task_td.join();

    std::cout << "task_thread:\t" << result.get() << '\n';
}
void task_lambda() {
    std::packaged_task task([](int a, int b) {
        return std::pow(a, b);
    });
    std::future result = task.get_future();

    task(2, 9);

    std::cout << "task_lambda:\t" << result.get() << '\n';
}


int main() {
    task_lambda();
}

错误消失了.即使我从不调用它,如何通过添加函数来更正程序?

gcc版本

gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)

Promgram用命令编译:

g++ -std=c++11 aa.cc -lpthread

在@ fedepad的帮助下,我通过用pthread替换lpthread获得了正确的输出.但我仍然混淆第二代码如何通过添加虚函数来工作!



1> fedepad..:

我使用以下版本的g ++尝试了你的第一个代码片段:

g ++(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609

并编译如下

g++ -o test_threads test_threads.cpp -std=c++11 -pthread  

我可以毫无问题地运行程序,并得到以下输出:

$ ./test_threads
task_lambda:512

如果我然后-lpthread按照您的方式使用以下内容

g++ -o test_threads test_threads.cpp -std=c++11 -lpthread  

我明白了

抛出'std :: system_error'实例后调用$ ./test_threads终止
what():未知错误-1
[1] 7890 abort ./test_threads

所以请-pthread用作旗帜而不是-lpthread.

以下https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59830中也提到了此行为

-pthread和之间有区别-lpthread.
查看g ++的手册页

-pthread
使用pthreads库添加对多线程的支持.此选项为预处理器链接器设置标志.

要查看为两者激活哪些标志,可以查看以下内容:

g++ -dumpspecs | grep pthread
g++ -dumpspecs | grep lpthread

可以清楚地看到,有些预处理器宏如果使用则不会被激活-lpthread.

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有