Linux中对pthread_create的引用未定义。

538
我从 https://computing.llnl.gov/tutorials/pthreads/ 网站上找到了下面这个演示。
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

但是当我在我的机器上编译它(运行Ubuntu Linux 9.04)时,我会得到以下错误:

corey@ubuntu:~/demo$ gcc -o term term.c
term.c: In function ‘main’:
term.c:23: warning: incompatible implicit declaration of built-in function ‘exit’
/tmp/cc8BMzwx.o: In function `main':
term.c:(.text+0x82): undefined reference to `pthread_create'
collect2: ld returned 1 exit status

这对我来说毫无意义,因为头文件包含了pthread.h,应该有pthread_create函数。你知道出了什么问题吗?

7
另外:根据平台的不同,您可能需要(a)针对线程使用不同的编译器,(b)针对线程使用不同的libc(即-lc_r),(c)使用-thread-threads或其他选项,而不是或除了-lpthread - ephemient
就在那个例子的上方,您会看到一个表格,其中包含正确的编译器命令,无论是GCC、IBM等。"雇用俄罗斯人"是正确的。 - Jonathon Reinhart
10
请问您能否取消标记我的答案,这样我就可以删除它(并标记实际正确的那个答案,也就是得票最高的那个)? - Pavel Minaev
6
编译时需要使用-lpthread - How Chen
12
解决方案 LDFLAGS= -pthread -lpthread。该指令将添加 -pthread-lpthread 标志到链接器标志中,以在编译过程中启用线程支持。 - dsnk
在主函数中使用 pthread_exit(NULL); 是必须的/良好的实践吗? - Vikram
16个回答

916

对于Linux来说,正确的命令是:

gcc -pthread -o term term.c

通常情况下,库应该遵循命令行上的源文件和目标文件,-lpthread不是一个“选项”,而是一个库规范。在只安装了libpthread.a的系统上,

gcc -lpthread ...

链接失败。

阅读此文此文进行详细解释。


6
这个解决方案有效,其他的都不行。另外,关于“库应该跟随源文件和对象”的建议非常好--能否提供引用或进一步解释? - sholsapp
9
@sholsapp 这是说明文:http://webpages.charter.net/ppluzhnikov/linker.html - Employed Russian
2
直到我在命令的最后加上了“-lpthread”,这个问题才得以解决。 gcc term.c -lpthread - CornSmith
5
对于使用CODEBLOCKS的任何人:将“-pthread”添加到项目构建选项->链接器设置->其他链接器选项。 - FreelanceConsultant
1
在仅安装了libpthread.a或libpthread.so的系统上,是吗? - Accountant م
显示剩余6条评论

55

对于Linux,正确的命令是:

gcc -o term term.c -lpthread
  1. 编译命令后面要加上"-lpthread",这个命令会告诉编译器使用pthread.h库来执行程序。
  2. gcc -l命令用于链接库文件,链接时不需要在库名前加上lib前缀。

1
在您的平台上存在具有相同功能的标准标志时,使用非标准标志并不是一个好主意。 - David Schwartz
这对我起作用了...其他解决方案没有。 - Edward Gaere

45

在Eclipse中

属性 -> C / C ++构建 -> 设置 -> GCC C ++链接器 -> 在顶部添加“pthread”库


同样的提示适用于code::project(我认为其他IDE也是如此)。 - Fil
1
我知道这可能有点晚了。如果您在属性中找不到C/C++构建设置(我找不到,也许是由于安装或错误),那么可以直接使用CMakeLists.txt文件进行较低级别的解决方法。 您需要在add_executable命令之前插入SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")。这将指示链接器执行相同操作(有关更多帮助,请参见CMAKE_EXE_LINKER_FLAGSSET文档)。 - Avneesh Mishra

36

在Linux终端中,对我有效的编译命令是使用以下命令进行编译(假设要编译的C文件名为test.c):

gcc -o test test.c -pthread

希望能帮助到某些人!


已在Ubuntu 16.x中确认。 - ingconti

33

如果您正在使用cmake,则可以使用:

add_compile_options(-pthread)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")

29

我认为在CMake中添加pthread的正确方法如下:

find_package (Threads REQUIRED)

target_link_libraries(helloworld
    ${CMAKE_THREAD_LIBS_INIT}
)

5
这将产生相同的效果,但使用Threads :: Threads目标而不是CMAKE_THREAD_LIBS_INIT变量。 - Aidan Gallagher

20

11

请按照以下方式编译:gcc demo.c -o demo -pthread。


8
在 Visual Studio 2019 中,要在项目的属性页中指定 -pthread,请按照以下步骤操作:

连接器 -> 命令行 -> 其他选项

在文本框中输入 -pthread


当我这样做时,我会收到错误信息“pthread:没有那个文件或目录”。 - Niko O
我的链接在发布版本中失败了,但在调试版本中成功了。原来发布版本中缺少了“-pthread”。确保两个构建环境匹配。 - J. Martin

4

由于没有一个答案完全符合我的需求(使用MSVS Code),因此我在这里补充一下我在此IDE和CMAKE构建工具中的经验。

步骤1:确保在您的.cpp(或如果需要的话.hpp)中已经包含了以下内容:

#include <functional>

第二步,针对MSVSCode IDE用户: 将以下这行内容添加到您的c_cpp_properties.json文件中:

"compilerArgs": ["-pthread"],

在 c_cpp_properties.json 文件中添加此行

对于 CMAKE 构建工具用户,请将此行添加到您的 CMakeLists.txt 中。

set(CMAKE_CXX_FLAGS "-pthread")

注意:添加标记-lpthread(而不是-pthread)导致链接失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接