gcc -lpthread和gcc -pthread的区别

转载地址:https://blog.csdn.net/skylinethj/article/details/38569243

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

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 
  6. #include 
  7. #include 
  8. #include "errors.h"
  9.  
  10. pid_t self_pid;        /* pid of current process */
  11. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  12.  
  13. void fork_prepare(void)
  14. {
  15.     pthread_mutex_lock(&mutex);
  16. }
  17.  
  18. void fork_parent(void)
  19. {
  20.     pthread_mutex_unlock(&mutex);
  21. }
  22.  
  23. void fork_child(void)
  24. {
  25.     self_pid = getpid();
  26.     pthread_mutex_unlock(&mutex);
  27. }
  28.  
  29. void *thread_routine(void *arg)
  30. {
  31.     pid_t child_pid;
  32.  
  33.     child_pid = fork();
  34.     if(child_pid == (pid_t)-1)
  35.         errno_abort("Fork");
  36.  
  37.     pthread_mutex_lock(&mutex);
  38.     pthread_mutex_unlock(&mutex);
  39.     printf("After fork: %d (%d)\n", child_pid, self_pid);
  40.     if(child_pid != 0){ // parent process
  41.         if ((pid_t)-1 == waitpid(child_pid, (int*)0, 0))
  42.             errno_abort("Wait for child");
  43.     }
  44.     return NULL;
  45. }
  46.  
  47. int main(int argc, char *argv[])
  48. {
  49.     pthread_t fork_thread;
  50.     int atfork_flag = 1;
  51.  
  52.     if(argc > 1)
  53.         atfork_flag = atoi (argv[1]);
  54.     if(atfork_flag){
  55.         pthread_atfork(fork_prepare, fork_parent, fork_child);
  56.     }
  57.     self_pid = getpid();
  58.     pthread_mutex_lock(&mutex);
  59.  
  60.     pthread_create(&fork_thread, NULL, thread_routine, NULL);
  61.     sleep(5);
  62.     pthread_mutex_unlock (&mutex);
  63.     pthread_join(fork_thread, NULL);
  64.  
  65.     return 0;
  66. }

编译运行结果:

  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.  
  7. digdeep@ubuntu:~$ man gcc | grep pthread
  8.            -mvxworks -G num -pthread
  9.            -mno-unaligned-doubles -mv8plus -mno-v8plus -mvis -mno-vis -threads -pthreads
  10.            -pthread
  11.            implies -pthread, and thus is only supported on targets that have support for
  12.            -pthread.
  13.            implies -pthread, and thus is only supported on targets that have support for
  14.            -pthread.
  15.            option and the -pthread option are incompatible.
  16.        -pthread
  17.            Adds support for multithreading with the pthreads library. This option sets flags for
  18.        -pthreads
  19.        -pthread
  20.            This is a synonym for -pthreads.
  21. digdeep@ubuntu:~$ 
  22. digdeep@ubuntu:~$ man gcc | grep lpthread
  23. digdeep@ubuntu:~$ 
  24. 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.  
  5. -pthreads
  6.      Add support for multithreading using the POSIX threads library. This option sets
  7.      flags for both the preprocessor and linker. This option does not affect the thread
  8.      safety of object code produced by the compiler or that of libraries supplied with it.
  9.  
  10. -pthread
  11.            This is a synonym for -pthreads.

从上面的 man gcc中的详细说明可以看出:

1)-pthread和-pthreads的含义是相同的。

2)-pthread或者-pthreads的编译选项是用于在编译时增加多线程的支持。该选项同时对“预处理器”和“链接器”产  

      生作用。

3)-pthread或者-pthreads的编译选项,即不影响编译器产生的目标代码的线程安全性,也不影响对提供的支持

     多线程的函数库libraries(的选择).(gcc 会自动链接系统当前版本推荐的 thread lib 以及对应的 thread 

     safe 的 c func。 http://kasicass.blog.163.com/blog/static/395619200992410313759/)

 

但是,下面的输出却又说明,我们不能使用 -pthreads:

  1. digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -pthreads -o atfork atfork.c 
  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。

 

另:下面的英文文档详细说明了相关的情况。

http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_concurrency.html

该文档的摘要:

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.  
  4. *lib:
  5. %{pthread:-lpthread} %{shared:-lc} %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}

%{pthread:-lpthread} 与上面的说明有点矛盾!!有点糊涂了。

你可能感兴趣的:(linux-app)