gcc -lpthread和gcc -pthread的区别

时间:2021-12-12 17:30:34

在编译多线程程序时遇到了

undefined reference to `pthread_create'

在网上找了很多都说加上编译开关-lpthread

但是问题没有解决,后来找到下面的一篇博文才知道问题所在...


在编译下面的代码时,碰到了undefined reference to `pthread_atfork'的错误:

代码来自《POSIX多线程程序设计》
  1. /*
  2.  * atfork.c
  3.  * Demonstrate the use of "fork handlers" to protect data invariants across a fork.
  4.  */
  5. #include <sys/types.h>
  6. #include <pthread.h>
  7. #include <sys/wait.h>
  8. #include "errors.h"

  9. pid_t self_pid;        /* pid of current process */
  10. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

  11. void fork_prepare(void)
  12. {
  13.     pthread_mutex_lock(&mutex);
  14. }

  15. void fork_parent(void)
  16. {
  17.     pthread_mutex_unlock(&mutex);
  18. }

  19. void fork_child(void)
  20. {
  21.     self_pid = getpid();
  22.     pthread_mutex_unlock(&mutex);
  23. }

  24. void *thread_routine(void *arg)
  25. {
  26.     pid_t child_pid;

  27.     child_pid = fork();
  28.     if(child_pid == (pid_t)-1)
  29.         errno_abort("Fork");

  30.     pthread_mutex_lock(&mutex);
  31.     pthread_mutex_unlock(&mutex);
  32.     printf("After fork: %d (%d)\n", child_pid, self_pid);
  33.     if(child_pid != 0){ // parent process
  34.         if ((pid_t)-== waitpid(child_pid, (int*)0, 0))
  35.             errno_abort("Wait for child");
  36.     }
  37.     return NULL;
  38. }

  39. int main(int argc, char *argv[])
  40. {
  41.     pthread_t fork_thread;
  42.     int atfork_flag = 1;

  43.     if(argc > 1)
  44.         atfork_flag = atoi (argv[1]);
  45.     if(atfork_flag){
  46.         pthread_atfork(fork_prepare, fork_parent, fork_child);
  47.     }
  48.     self_pid = getpid();
  49.     pthread_mutex_lock(&mutex);

  50.     pthread_create(&fork_thread, NULL, thread_routine, NULL);
  51.     sleep(5);
  52.     pthread_mutex_unlock (&mutex);
  53.     pthread_join(fork_thread, NULL);

  54.     return 0;
  55. }
编译运行结果:
  1. digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -lpthread -o atfork atfork./tmp/cckSrItT.o: In function `main':
  2. atfork.c:(.text+0x195): undefined reference to `pthread_atfork'
  3. collect2: ld returned 1 exit status
  4. digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -pthread -o atfork atfork.
  5. digdeep@ubuntu:~/pthread/learnthread$ ./atfork 
  6. After fork: 2637 (2635)
  7. After fork: 0 (2637)
  8. digdeep@ubuntu:~/pthread/learnthread$
于是想搞清楚 -lpthread-pthread的区别:
  1. digdeep@ubuntu:~$ gcc --version
  2. gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
  3. Copyright (C) 2010 Free Software Foundation, Inc.
  4. This is free software; see the source for copying conditions. There is NO
  5. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  6. digdeep@ubuntu:~$ man gcc | grep pthread
  7.            -mvxworks -G num -pthread
  8.            -mno-unaligned-doubles -mv8plus -mno-v8plus -mvis -mno-vis -threads -pthreads
  9.            -pthread
  10.            implies -pthread, and thus is only supported on targets that have support for
  11.            -pthread.
  12.            implies -pthread, and thus is only supported on targets that have support for
  13.            -pthread.
  14.            option and the -pthread option are incompatible.
  15.        -pthread
  16.            Adds support for multithreading with the pthreads library. This option sets flags for
  17.        -pthreads
  18.        -pthread
  19.            This is a synonym for -pthreads.
  20. digdeep@ubuntu:~$ 
  21. digdeep@ubuntu:~$ man gcc | grep lpthread
  22. digdeep@ubuntu:~$ 
  23. digdeep@ubuntu:~$
从上面的输出可以看到,目前gcc 4.5.2中已经没有了关于 -lpthread的介绍了。所以以后的多线程编译应该用
 -pthread,而不是-lpthread。

仔细的阅读man gcc中的关于pthread的介绍:
  1. -pthread
  2.      Adds support for multithreading with the pthreads library. This option sets flags for
  3.      both the preprocessor and linker.

  4. -pthreads
  5.      Add support for multithreading using the POSIX threads library. This option sets
  6.      flags for both the preprocessor and linker. This option does not affect the thread
  7.      safety of object code produced by the compiler or that of libraries supplied with it.

  8. -pthread
  9.            This is a synonym for -pthreads.
从上面的 man gcc中的详细说明可以看出:
1)-pthread和-pthreads的含义是相同的。
2)-pthread或者-pthreads的编译选项是用于在编译时增加多线程的支持。该选项同时对“预处理器”和“链接器”产  
      生作用。
3)-pthread或者-pthreads的编译选项,即不影响编译器产生的目标代码的线程安全性,也不影响对提供的支持
     多线程的函数库libraries(的选择).( g cc 会自动链接系统当前版本推荐的 thread lib 以及对应的 thread 

但是,下面的输出却又说明,我们不能使用 -pthreads:
  1. digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -pthreads -o atfork atfork.
  2. gcc: unrecognized option '-pthreads'
  3. /tmp/ccZZmWbD.o: In function `main':
  4. atfork.c:(.text+0x195): undefined reference to `pthread_atfork'
  5. atfork.c:(.text+0x1cf): undefined reference to `pthread_create'
  6. atfork.c:(.text+0x1fb): undefined reference to `pthread_join'
  7. collect2: ld returned 1 exit status
所以: 一句话,我们现在应该使用 -pthread 而不是 -lpthread

另:下面的英文文档详细说明了相关的情况。
该文档的摘要:
When you link a multithreaded application, you will probably need to add a library or flag to g++. This is a very non-standardized area of GCC across ports. Some ports support a special flag (the spelling isn't even standardized yet) to add all required macros to a compilation (if any such flags are required then you must provide the flag for all compilations not just linking) and link-library additions and/or replacements at link time. The documentation is weak. Here is a quick summary to display how ad hoc this isOn Solaris, both -pthreads and -threads (with subtly different meanings) are honoredOn OSF, -pthread and -threads (with subtly different meanings) are honoredOn Linux/i386, -pthread is honoredOn FreeBSD, -pthread is honored. Some other ports use other switches. AFAIK(就我所知), none of this is properly documented anywhere other than in ``gcc -dumpspecs'' (look at lib and cpp entries).

下面是摘录自命令 gcc -dumpspecs的输出:
  1. *cpp:
  2. %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}

  3. *lib:
  4. %{pthread:-lpthread} %{shared:-lc} %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}
%{pthread:-lpthread 与上面的说明有点矛盾!!有点糊涂了。

转自:http://blog.chinaunix.net/uid-25909722-id-3026989.html