gcc -lpthread和gcc -pthread的区别

简介: 在编译下面的代码时,碰到了undefined reference to `pthread_atfork'的错误:代码来自《POSIX多线程程序设计》/*  * atfork.c  * Demonstrate the use of "fork handlers" to protect data invariants across a fork.
在编译下面的代码时,碰到了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)-1 == 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.c /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.c
  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 is: On Solaris, both -pthreads and -threads (with subtly different meanings) are honored. On OSF, -pthread and -threads (with subtly different meanings) are honored. On Linux/i386, -pthread is honored. On 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 与上面的说明有点矛盾!!有点糊涂了。NND!




相关文章
|
3月前
|
NoSQL 编译器 开发工具
006.gcc编译器
gcc是什么?
43 0
006.gcc编译器
|
4月前
|
存储 NoSQL 算法
从一个crash问题展开,探索gcc编译优化细节
问题分析的过程也正是技术成长之路,本文以一个gcc编译优化引发的crash为切入点,逐步展开对编译器优化细节的探索之路,在分析过程中打开了新世界的大门……
405 1
|
3天前
|
C语言
转载 - gcc/ld 动态连接库和静态连接库使用方法
本文介绍了如何在GCC中实现部分程序静态链接、部分动态链接。使用`-Wl`标志传递链接器参数,`-Bstatic`强制链接静态库,`-Bdynamic`强制链接动态库。
14 0
|
30天前
|
编译器 C语言 C++
列举gcc 常见和有用的编译警告选项
列举gcc 常见和有用的编译警告选项
11 0
|
30天前
|
编译器 C语言
gcc编译警告:warning: suggest parentheses around assignment used as truth value
gcc编译警告:warning: suggest parentheses around assignment used as truth value
16 0
|
1月前
|
编译器 Linux C语言
gcc编译器的使用方法
gcc编译器的使用方法
20 1
|
2月前
|
编译器 C语言
gcc/g++语法
gcc/g++语法
|
4月前
|
C语言
gcc静态编译/usr/bin/ld: cannot find -lc
gcc静态编译/usr/bin/ld: cannot find -lc
|
5月前
|
编译器 程序员 C语言
gcc的编译过程和gcc与g++的区别
gcc的编译过程和gcc与g++的区别
52 0
|
6月前
|
C语言
编译安装gcc
编译安装gcc