【转载】gcc -lpthread和gcc -pthread的区别
转自: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.
*/
#include <sys/types.h>
#include <pthread.h>
#include <sys/wait.h>
#include "errors.h"
pid_t self_pid; /* pid of current process */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void fork_prepare(void)
{
pthread_mutex_lock(&mutex);
}
void fork_parent(void)
{
pthread_mutex_unlock(&mutex);
}
void fork_child(void)
{
self_pid = getpid();
pthread_mutex_unlock(&mutex);
}
void *thread_routine(void *arg)
{
pid_t child_pid;
child_pid = fork();
if(child_pid == (pid_t)-1)
errno_abort("Fork");
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
printf("After fork: %d (%d)\n", child_pid, self_pid);
if(child_pid != 0){ // parent process
if ((pid_t)-1 == waitpid(child_pid, (int*)0, 0))
errno_abort("Wait for child");
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t fork_thread;
int atfork_flag = 1;
if(argc > 1)
atfork_flag = atoi (argv[1]);
if(atfork_flag){
pthread_atfork(fork_prepare, fork_parent, fork_child);
}
self_pid = getpid();
pthread_mutex_lock(&mutex);
pthread_create(&fork_thread, NULL, thread_routine, NULL);
sleep(5);
pthread_mutex_unlock (&mutex);
pthread_join(fork_thread, NULL);
return 0;
}
编译运行结果:
digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -lpthread -o atfork atfork.c /tmp/cckSrItT.o: In function `main': atfork.c:(.text+0x195): undefined reference to `pthread_atfork' collect2: ld returned 1 exit status digdeep@ubuntu:~/pthread/learnthread$ gcc -Wall -pthread -o atfork atfork.c digdeep@ubuntu:~/pthread/learnthread$ ./atfork After fork: 2637 (2635) After fork: 0 (2637) digdeep@ubuntu:~/pthread/learnthread$
于是想搞清楚 -lpthread和-pthread的区别:
digdeep@ubuntu:~$ gcc --version
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
digdeep@ubuntu:~$ man gcc | grep pthread
-mvxworks -G num -pthread
-mno-unaligned-doubles -mv8plus -mno-v8plus -mvis -mno-vis -threads -pthreads
-pthread
implies -pthread, and thus is only supported on targets that have support for
-pthread.
implies -pthread, and thus is only supported on targets that have support for
-pthread.
option and the -pthread option are incompatible.
-pthread
Adds support for multithreading with the pthreads library. This option sets flags for
-pthreads
-pthread
This is a synonym for -pthreads.
digdeep@ubuntu:~$
digdeep@ubuntu:~$ man gcc | grep lpthread
digdeep@ubuntu:~$
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(的选择).(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。
另:下面的英文文档详细说明了相关的情况。
该文档的摘要:
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} 与上面的说明有点矛盾!!有点糊涂了。

浙公网安备 33010602011771号