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的项目,并且我在Properties-> C / C Build-> Settings中使用了-std = c 11 ->工具设置->其他标志,以便可以使用所有C 11功能进行编译。
我还在C / C通用符号中设置了
1 2 3 | undefined reference to pthread_create, ..asio-1.10.6\\include\\asio\\detail\\impl\\posix_thread.ipp and posix_tss_ptr.hpp |
所以问题是,由于我使用的是C 11,并且指定了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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 |
嫌疑人1 -pthread
与大多数人相反,C 11不需要
可疑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
中
1 2 3 4 | # 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仍在POSIX THREADS或Windows上针对以下所示的signal_blocker.hpp进行回复。这就是ASIO仍然需要pthread的原因。
1 2 3 4 5 6 7 | #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。
同样,对于g 4.9.2,非ASIO C 11线程不需要-pthread,但是独立的ASIO需要它。在g 4.9.2(基于Eclipse的Xilinx SDK)中没有-pthread的情况下正确构建了以下代码:
1 2 3 4 5 6 7 8 9 10 | #include <thread> void test() { for(int i=0;i<100;i++); } int main() { std::thread thread1(test); thread1.join(); return 0; } |
用C 11编写程序的事实与是否
它不需要与
库,如果它需要Posix线程。
C 11提供了
库必须使用某些本机实现该类的功能
目标系统托管的线程API。 GCC使用
因此,您无法构建使用以下命令创建
GCC,除非您将其与
LATER
I actually built a program without pthread using std::std just using -std=c++11
我认为您对某些GCC Windows端口感到误解和困惑
默认情况下链接
可以使用TDM-GCC 4.9.2在Windows中成功构建它,因此:
1 | >g++ -std=c++11 -o test_thread thread.cpp |
但是,如果您以详细模式进行构建:
1 | >g++ -v -std=c++11 -o test_thread thread.cpp |
您会看到很多库选项都传递给了链接器
在幕后,尤其是
1 2 | >g++ -v -std=c++11 -o test_thread thread.cpp 2>&1 | grep -Po 'pass-through=-lpthread' - pass-through=-lpthread |
在Linux上,除非您询问以下内容,否则您将不会链接
1 2 3 4 | $ 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 |
执行代码期间
g ssss(您的代码名称).cpp -std = c 11 -pthread
它将起作用
1. std :: thread不需要-pthread
这是我从ASIO中挖掘出来的内容,首先让我展示一个简单的示例。在CentOS 6.5 32位和Eclipse中,使用g 4.9.3,以下代码仅使用-std = c 11构建,而无需说-lpthread
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | std::string make_greeting_string() { auto now = std::chrono::system_clock::now(); const auto in_time_t = std::chrono::system_clock::to_time_t(now); std::stringstream ss; //ss << std::put_time(std::localtime(&in_time_t),"%Y-%m-%d %X"); ss <<"Greetings"<<45; return ss.str(); } int main() { std::thread thread1(make_greeting_string); //test2(); thread1.join(); cout <<"!!!Hello World!!!" << endl; // prints !!!Hello World!!! return 0; } |
一旦我在主目录中添加了tes2(),它就会失败,并带有对pthread_create的未定义引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | void *PrintHello(void *threadid) { long tid; tid = (long)threadid; std::cout<<"Hello World! It's me, thread #%ld!"<<tid<<std::endl; pthread_exit(NULL); } void test2() { pthread_t threads[NUM_THREADS]; int rc; long t; for(t=0;t<NUM_THREADS;t++){ std::cout<<"In main: creating thread %ld"<<t<<std::endl; rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ std::cout<<"ERROR; return code from pthread_create() is"<<rc<<std::endl; exit(-1); } } } |
2. ASIO依赖于-pthread的来源
首先,独立的ASIO中有使用posix线程但也可以使用std的代码。定义两者时,应重新排列顺序以首先使用std。来自static_mutex.hpp第27
行的代码示例
1 2 3 4 | #elif defined(ASIO_HAS_PTHREADS) #include"asio/detail/posix_static_mutex.hpp" #elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #include"asio/detail/std_static_mutex.hpp" |
第二,仍然有两个文件需要posix:signal_blocker.hpp和tss_ptr.hpp。由于仅支持Windows和POSIX,make将失败
我不知道是否可以完全重写两个文件以使用c 11,但是这两个文件是-lpthread而不是std :: thread依赖项的来源。
更新
影响signal_set_service.ipp
1 2 3 4 5 6 7 8 9 10 11 12 13 | case asio::io_service::fork_child: if (state->fork_prepared_) { asio::detail::signal_blocker blocker; close_descriptors(); open_descriptors(); int read_descriptor = state->read_descriptor_; state->fork_prepared_ = false; lock.unlock(); reactor_.register_internal_descriptor(reactor::read_op, read_descriptor, reactor_data_, new pipe_read_op); } break; |
和select_reactor.ipp
1 2 3 4 5 6 7 | { #if defined(ASIO_HAS_IOCP) asio::detail::signal_blocker sb; thread_ = new asio::detail::thread( bind_handler(&select_reactor::call_run_thread, this)); #endif // defined(ASIO_HAS_IOCP) } |