未定义的引用`pthread_create'使用ASIO和std :: thread进行C ++ 11应用程序时出错 [英] undefined reference to `pthread_create' Error when making C++11 application with ASIO and std::thread
问题描述
我设置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屋!