C++:带有 packaged_task 的核心转储

标签 c++ c++11 gcc g++

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

#include <future>
#include <iostream>
#include <cmath>

void task_lambda() {
    std::packaged_task<int(int,int)> task([](int a, int b) {
        return std::pow(a, b);
    });
    std::future<int> 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<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (__once=..., __f=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x1246d>)
at /usr/include/c++/5/mutex:746
#8  0x0000000000403eb2 in std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) (
this=0x61ec30, __res=..., __ignore_failure=false) at /usr/include/c++/5/future:387
#9  0x0000000000402b76 in std::__future_base::_Task_state<task_lambda()::<lambda(int, int)>, std::allocator<int>, int(int, int)>::_M_run(<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17680>, <unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17685>) (this=0x61ec30, __args#0=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17680>, 
__args#1=<unknown type in /home/ace/test/a.out, CU 0x0, DIE 0x17685>) at /usr/include/c++/5/future:1403
#10 0x00000000004051c1 in std::packaged_task<int (int, int)>::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 <iostream>
#include <cmath>
#include <future>
#include <thread>
int f(int x, int y) { return std::pow(x,y); }
void task_thread() {
    std::packaged_task<int(int,int)> task(f);
    std::future<int> 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<int(int,int)> task([](int a, int b) {
        return std::pow(a, b);
    });
    std::future<int> result = task.get_future();

    task(2, 9);

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


int main() {
    task_lambda();
}

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

海湾合作委员会版本

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

用命令编译的程序:

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

在@fedepad 的帮助下,我通过将 lpthread 替换为 pthread 获得了正确的输出。 但我仍然对第二个代码如何通过添加一个虚拟函数感到困惑!

最佳答案

我使用以下版本的 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  

我明白了

$ ./test_threads terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
[1] 7890 abort ./test_threads

所以请使用 -pthread 作为标志,而不是 -lpthread

下面也提到了这种行为
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59830

-pthread-lpthread是有区别的。
查看 g++ 的手册页

-pthread
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.

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

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

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

关于C++:带有 packaged_task 的核心转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41790363/

相关文章:

android - 线程中的数学函数返回错误值,使用 android ndk

c++ - 进程A直接写入进程B的数据成员

c++ - 调用非默认构造函数作为成员初始化

c++ - 错误 C2672: 'operator __surrogate_func':使用 std::upper_bound 时未找到匹配的重载函数

c - C中同一函数的多个隐式声明

c++ - 窗口标题 Qt 中的小部件

c++ - 从进程加载的 DLL 调用另一个进程中的方法

c++ - 修复循环变量的 -Wconversion GCC 警告

c++ - 如何在 powerpc 中使用内联汇编获取 cpuid?

c - 为什么 pow 函数比简单操作慢?