未定义的引用`pthread_create'使用ASIO和std :: thread进行C ++ 11应用程序时出错 [英] undefined reference to `pthread_create' Error when making C++11 application with ASIO and std::thread

查看:2541
本文介绍了未定义的引用`pthread_create'使用ASIO和std :: thread进行C ++ 11应用程序时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设置Eclipse(实际上是Xilinx SDK但基于Eclipse)和g ++ 4.9.2,编译一个使用独立ASIO的项目,我在属性 - > C / C ++中使用了-std = c ++ 11



我还设置了 ASIO_HAS_STD_THREAD,这样可以使用所有的C ++ 11特性来编译。 ASIO_STANDALONE 等等,在C / C ++通用符号,我希望ASIO头将使用 std :: thread 而不是 pthread 。但是,我仍然看到错误从make:

 未定义引用pthread_create,
..asio-1.10.6 \\ \\include\asio\detail\asio\detail\impl\poset/\\impl\posix_thread.ipp
and posix_tss_ptr.hpp

所以问题是,因为我使用C ++ 11,并指定 ASIO_HAS_STD_THREAD 但不是 ASIO_HAS_PTHREADS 根据ASIO中的thread.hpp, posix_thread.ipp 不应该包含(通过posix_thread.hpp):

  #if!defined(ASIO_HAS_THREADS)
#includeasio / detail / null_thread.hpp
#elif defined(ASIO_WINDOWS)
# (UNDER_CE)
#includeasio / detail / wince_thread.hpp
#else
#includeasio / detail / win_thread.hpp
#endif
# elif defined(ASIO_HAS_PTHREADS)
#includeasio / detail / posix_thread.hpp
#elif defined(ASIO_HAS_STD_THREAD)
#includeasio / detail / std_thread.hpp
# else
#error只支持Windows,POSIX和std :: thread!
#endif



可疑1 -pthread



与大多数人相信,C ++ 11不需要 -pthread ,我已经尝试编译一个简单的项目,而不用 -pthread 。但是,如果我错了,你可以纠正我。当我在链接器选项中插入 -pthread 时,它会进行编译,但是如果没有必要,我觉得我不想要pthread。



可疑2 - ASIO makefile



当我搜索posix_tss_ptr.hpp时,我在Makefile.am中也找到了。我不知道这是否影响错误?



那么问题的原因是什么?如果不是上述两个嫌疑人?我希望解决方案仍然可以使用纯C ++ 11方式,如果我的推理是正确的,不使用pthread。



更新



我发现ASIO_HAS_PTHREADS不是由我定义的,这就是为什么ASIO在某处使用POSIX线程,然后链接器需要选项-pthread。然后我使用#error指令跟踪到asio / detail / signal_blocker.hpp。只有两个地方,它被定义,它们在ASIO config.hpp

 #如果定义(ASIO_HAS_BOOST_CONFIG)&& ;定义(BOOST_HAS_PTHREADS)
#define ASIO_HAS_PTHREADS 1
#elif defined(_POSIX_THREADS)
#define ASIO_HAS_PTHREADS 1

ASIO仍然回复POSIX THREADS或Windows的signal_blocker.hpp如下所示。这就是为什么ASIO仍然需要pthread。

  #if!defined(ASIO_HAS_THREADS)|| defined(ASIO_WINDOWS)\ 
|| defined(ASIO_WINDOWS_RUNTIME)\
|| defined(__ CYGWIN__)|| defined(__ SYMBIAN32__)
typedef null_signal_blocker signal_blocker;
#elif defined(ASIO_HAS_PTHREADS)
typedef posix_signal_blocker signal_blocker;
#endif

而_PTHREADS是从gnu交叉编译器定义的(arm-xilinx-linux -gnueabi)包括诸如features.h,posix_opt.h等文件。我不会跟踪哪个真正定义的宏,但ASIO是使用_POSIX_THREADS的源,所以链接器选项-pthread应该在那里。



同样,非ASIO C ++ 11线程不需要-pthread的g ++ 4.9.2,但独立ASIO需要它。下面的代码在g ++ 4.9.2(基于Eclipse的Xilinx SDK)中没有-pthread的情况下正确构建:

  #include< thread> 
void test(){
for(int i = 0; i< 100; i ++);
}
int main()
{
std :: thread thread1(test);
thread1.join();
return 0;
}


解决方案

用C ++ 11编写与是否或
无关,不需要与 pthread 库链接。如果需要Posix线程,需要链接
库。



C ++ 11提供 std :: thread 类和每个符合的编译器标准
库必须使用目标系统托管的一些本地
线程API实现该类的功能。 GCC使用 pthreads
实现它,因此你不能创建任何创建 std :: thread 对象的程序与
GCC除非你链接它与 -pthread 。此事实与 asio 无关。



稍后


我实际上使用std :: std构建了一个没有pthread的程序,使用-std = c ++ 11


我想你是错误和困惑的事实,一些Windows端口的GCC
链接 libpthread 默认情况下。例如。如果你的示例程序在 thread.cpp I
可以成功地建立在Windows与TDM-GCC 4.9.2所以:

 > g ++ -std = c ++ 11 -o test_thread thread.cpp 

但是如果你以详细模式构建它:

 > g ++ -v  - std = c ++ 11 -o test_thread thread.cpp 

你可以看到很多库选项被传递到链接器
幕后,特别是 -lpthread

 > g ++ -v -std = c ++ 11 -o test_thread thread.cpp 2& 1 | grep -Po'pass-through = -lpthread' -  
pass-through = -lpthread

在Linux上,除非你问:<$ p
$ b

 ,否则不会链接 libpthread  $ g ++ -std = c ++ 11 -o test_thread thread.cpp 
/tmp/ccpyEles.o:在函数`std :: thread :: thread< void(&)()>(void ;}())':
thread.cpp :( .text._ZNSt6threadC2IRFvvEJEEEOT_DpOT0 _ [_ ZNSt6threadC5IRFvvEJEEEOT_DpOT0 _] + 0x7d):未定义引用`pthread_create'
collect2:error:ld返回1退出状态


I set Eclipse (Actually Xilinx SDK but based on Eclipse), and g++4.9.2, to compile a project which uses standalone ASIO and I used -std=c++11 in the Properties -> C/C++ Build -> Settings -> Tool Settings -> Other flags so it can compile using all C++11 features.

I also set ASIO_HAS_STD_THREAD, ASIO_STANDALONE and so on in C/C++ General Symbols, and I expect that the ASIO header will use std::thread instead of pthread. However, I still see Error from make:

undefined reference to pthread_create, 
..asio-1.10.6\include\asio\detail\impl\posix_thread.ipp
and posix_tss_ptr.hpp

so the problem is, since I am using C++11, and specified ASIO_HAS_STD_THREAD but not ASIO_HAS_PTHREADS, the posix_thread.ipp should not be even included (through posix_thread.hpp), according to thread.hpp in ASIO:

#if !defined(ASIO_HAS_THREADS)
# include "asio/detail/null_thread.hpp"
#elif defined(ASIO_WINDOWS)
# if defined(UNDER_CE)
#  include "asio/detail/wince_thread.hpp"
# else
#  include "asio/detail/win_thread.hpp"
# endif
#elif defined(ASIO_HAS_PTHREADS)
# include "asio/detail/posix_thread.hpp"
#elif defined(ASIO_HAS_STD_THREAD)
# include "asio/detail/std_thread.hpp"
#else
# error Only Windows, POSIX and std::thread are supported!
#endif

Suspect 1 -pthread

Contrary to most people believe, C++11 doesn't need the -pthread and I have tried to compile a simple project without -pthread in Eclipse. However, you can correct me if I am wrong. When I put -pthread in the linker option, it does compile, however I felt I don't want the pthread if not necessary.

Suspect 2 - ASIO makefile

When I search the posix_tss_ptr.hpp, I found also in Makefile.am. I wonder whether this affect the error?

So what is the cause of the problem? If not the above two suspect? I hope the solution can be still using pure C++11 way, not to use pthread if my reasoning is correct.

Update

I found that ASIO_HAS_PTHREADS is defined not by me and that's why ASIO uses POSIX threads somewhere and the linker then needs the option -pthread. Then I traced down to the asio/detail/signal_blocker.hpp by using #error directive. There are only two places that it is defined and they are in ASIO config.hpp

#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
#   define ASIO_HAS_PTHREADS 1
#  elif defined(_POSIX_THREADS)
#   define ASIO_HAS_PTHREADS 1

ASIO still replies on POSIX THREADS or Windows for signal_blocker.hpp shown below. That's why ASIO still needs pthread.

#if !defined(ASIO_HAS_THREADS) || defined(ASIO_WINDOWS) \
  || defined(ASIO_WINDOWS_RUNTIME) \
  || defined(__CYGWIN__) || defined(__SYMBIAN32__)
typedef null_signal_blocker signal_blocker;
#elif defined(ASIO_HAS_PTHREADS)
typedef posix_signal_blocker signal_blocker;
#endif

And _PTHREADS is defined from the gnu cross compiler (arm-xilinx-linux-gnueabi) include files such as features.h, posix_opt.h, and etc. I am not going to track down which truly defined the macro, but ASIO is the source which uses _POSIX_THREADS and so the linker option -pthread should be there.

Again, non ASIO C++11 thread doesn't need -pthread for g++ 4.9.2 but standalone ASIO needs it. The following code is built correctly without -pthread in g++4.9.2 (Xilinx SDK which is based on Eclipse):

#include <thread>
void test() {
    for(int i=0;i<100;i++);
}
int main()
{
    std::thread thread1(test);
    thread1.join();
    return 0;
}

解决方案

The fact that a program is written in C++11 has no bearing on with whether or not it needs to be linked with the pthread library. It needs to link that library if it requires Posix threads.

C++11 provides the std::thread class and each conforming compiler's standard library must implement the functionality of that class using some native threads API hosted by the target system. GCC implements it using pthreads, so you cannot any build a program that creates std::thread objects with GCC unless you link it with -pthread. This fact is unconnected with asio.

LATER

I actually built a program without pthread using std::std just using -std=c++11

I think you are mistaken and confused by the fact that some Windows ports of GCC link libpthread by default. E.g. if your example program is in thread.cpp I can successfully build it in Windows with TDM-GCC 4.9.2 so:

>g++ -std=c++11 -o test_thread thread.cpp

But if you build it in verbose mode:

>g++ -v -std=c++11 -o test_thread thread.cpp

you can see that a great many library options are passed to the linker behind the scenes, in particular -lpthread:

>g++ -v -std=c++11 -o test_thread thread.cpp 2>&1 | grep -Po 'pass-through=-lpthread' -
pass-through=-lpthread

And on Linux you will not link libpthread unless you ask:

$ g++ -std=c++11 -o test_thread thread.cpp
/tmp/ccpyEles.o: In function `std::thread::thread<void (&)()>(void (&)())':
thread.cpp:(.text._ZNSt6threadC2IRFvvEJEEEOT_DpOT0_[_ZNSt6threadC5IRFvvEJEEEOT_DpOT0_]+0x7d): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status

这篇关于未定义的引用`pthread_create'使用ASIO和std :: thread进行C ++ 11应用程序时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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