【转载】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 
 
但是,下面的输出却又说明,我们不能使用 -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 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} 与上面的说明有点矛盾!!有点糊涂了。
posted @ 2017-05-04 10:06  albertPaul  阅读(202)  评论(0)    收藏  举报