C ++:带有packaged_task的核心转储 [英] C++: Core dump with packaged_task

查看:153
本文介绍了C ++:带有packaged_task的核心转储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了一个奇怪的核心转储,我从 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();

任务(2,9);

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


int main(){
task_lambda();
}

我得到了这个

 在抛出'std :: system_error'实例后调用terminate 
what():未知错误-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在abort.c中的__GI_abort()中:89
#2 0x00007ffff7ae484d在__gnu_cxx :: __ verbose_terminate_handler()()from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
# 3 0x00007ffff7ae26b6在? ()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来自/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6的__cxa_throw()0x00007ffff7b0b7fe来自/ usr的std :: __ throw_system_error(int)() /lib/x86_64-linux-gnu/libstdc++.so.6
#7在std :: call_once中的0x0000000000404961< 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> (std :: once_flag&; void(std :: _ future_base :: _ state_baseV2 :: *&& amp; :_Result_base,std :: __ future_base :: _ Result_base :: _ Deleter>()> *,bool *),std :: __ future_base :: _State_baseV2 *& amp;< std :: function< std :: unique_ptr< std :: __future_base :: _ Result_base,std :: __ future_base :: _ Result_base :: _ Deleter>()&&& ;,; bool *&&)(__once = ...,__f =< home / / usr / include / c ++ / 5 / mutex:746
#8 0x0000000000403eb2 in std :: __ future_base :: _ St​​ate_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)在/ usr / include / c ++ / 5 / future:387
#9 0x0000000000402b76在std :: __ future_base :: _ Task_state< task_lambda()::< lambda(int,int)> ,std :: allocator< int> ;, int(int,int)> :: _ M_run(< / home / ace / test / a.out中的未知类型,CU 0x0,DIE 0x17680> ;,< /home/ace/test/a.out中的未知类型,CU 0x0,DIE 0x17685>) (this = 0x61ec30,__args#0 =< / home / ace / test / a.out中的未知类型,CU 0x0,DIE 0x17680> ;,
__args#1 =< test / a.out,CU 0x0,DIE 0x17685>)在/ usr / include / c ++ / 5 / future:1403
#10 0x00000000004051c1在std :: packaged_task< int(int,int)> :: operator在/ usr / include / c ++ / 5 / future:1547
#11 0x0000000000401c7d在task_lambda()上的()()(int,int)(this = 0x7fffffffdca0,__args#0 = 2,__args#1 = 9) .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)>任务(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()<< \\\
;
}
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();

任务(2,9);

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


int main(){
task_lambda();
}

错误消失了。我可以通过添加一个函数来纠正程序,即使我从来没有调用它?



gcc版本

  gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1〜16.04.4)

用命令编译的Promgram:

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

在@ fedepad的帮助下,我通过用pthread替换lpthread得到了正确的输出结果。 但我仍然困惑第二个代码是如何通过添加一个虚拟函数来实现的!

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


g ++(Ubuntu 5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609 p>

并用以下编译

  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
终止后调用抛出一个实例o f'std :: system_error'

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


I got a strange core dump which I copied from a part of code in 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();
}

I got this

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

The call stack is like below:

#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

Then I added some sample code into my program, it became

#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();
}

the error was gone. How can I correct the program by adding a function even though I never call it?

gcc version

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

Promgram compiled with command:

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

With @fedepad's help, I got correct output by replace lpthread with pthread. But I still confused how second code work by add a dummy function!

解决方案

I tried your first code snippet using the following version of g++:

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

and compiled with the following

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

and I can run the program with no problems, and getting the following output:

$ ./test_threads
task_lambda: 512

If I then use the -lpthread as you did with the following

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

I get

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

So please use -pthread as a flag and not -lpthread.

This behavior is also mentioned in the following
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59830

There's a difference between -pthread and -lpthread.
Looking at the man page for g++

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

To have a look to what flags are activated for both one can check with the following:

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

As one can clearly see, there are some preprocessor macros that are not activated if one is using -lpthread.

这篇关于C ++:带有packaged_task的核心转储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆