使用ASIO和std :: thread制作C++ 11应用程序时出现错误的`pthread_create'错误引用

Spl*_*ash 6 c++ pthreads c++11 stdthread

余组Eclipse(实际上赛灵思SDK但基于Eclipse),和g ++ 4.9.2,编译其使用独立ASIO一个项目,我在属性使用-std = C++ 11 - > C/C++编译 - >设置 - >工具设置 - >其他标志,以便可以使用所有C++ 11功能进行编译.

我也在ASIO_HAS_STD_THREAD, ASIO_STANDALONEC/C++通用符号中设置等等,我希望ASIO标题std::thread代替使用pthread.但是,我仍然看到来自make的错误:

undefined reference to pthread_create, 
..asio-1.10.6\include\asio\detail\impl\posix_thread.ipp
and posix_tss_ptr.hpp
Run Code Online (Sandbox Code Playgroud)

因此问题是,由于我使用C++ 11,和指定的ASIO_HAS_STD_THREAD但不是ASIO_HAS_PTHREADS,则posix_thread.ipp不应甚至包括(通过posix_thread.hpp),根据在ASIO thread.hpp:

#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
Run Code Online (Sandbox Code Playgroud)

怀疑1 -pthread

与大多数人认为的相反,C++ 11并不需要-pthread,我试图在没有-pthreadEclipse的情况下编译一个简单的项目.但是,如果我错了,你可以纠正我.当我-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中

#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
#   define ASIO_HAS_PTHREADS 1
#  elif defined(_POSIX_THREADS)
#   define ASIO_HAS_PTHREADS 1
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

而_PTHREADS从GNU交叉编译器定义(ARM-赛灵思的Linux gnueabi)包括文件,如features.h,posix_opt.h,等我不打算追查其真正定义的宏,但ASIO是使用_POSIX_THREADS的源代码,因此链接器选项-pthread应该在那里.

同样,非ASIO C++ 11线程对于g ++ 4.9.2不需要-pthread,但是独立的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;
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*han 13

程序是用C++ 11编写的,这与它是否需要与pthread库链接无关.如果它需要Posix线程,它需要链接该库.

C++ 11提供了std::thread类,每个符合标准的编译器的标准库必须使用目标系统托管的一些本机线程API来实现该类的功能.GCC使用它来实现它pthreads,所以你不能构建一个std::thread用GCC 创建对象的程序,除非你链接它-pthread.这个事实与之无关asio.

后来

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

我认为你被GCC的某些Windows端口libpthread默认链接的事实弄错了.例如,如果您的示例程序在thread.cpp我可以使用TDM-GCC 4.9.2在Windows中成功构建它,那么:

>g++ -std=c++11 -o test_thread thread.cpp
Run Code Online (Sandbox Code Playgroud)

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

>g++ -v -std=c++11 -o test_thread thread.cpp
Run Code Online (Sandbox Code Playgroud)

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

>g++ -v -std=c++11 -o test_thread thread.cpp 2>&1 | grep -Po 'pass-through=-lpthread' -
pass-through=-lpthread
Run Code Online (Sandbox Code Playgroud)

在Linux上你不会链接,libpthread除非你问:

$ 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
Run Code Online (Sandbox Code Playgroud)


小智 6

在执行代码时使用 g++ ssss(your code name).cpp -std=c++11 -pthread

它会工作