/.. .../voice_demo: hidden symbol `pthread_atfork' in /opt/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/bin/../aarch64-linux-gnu/libc/usr/lib/aarch64-linux-gnu/libpthread_nonshared.a(pthread_atfork.oS) is referenced by DSO
调用关系如下:
A->B.so->多线程函数库
A依赖B的动态库文件。B动态库又依赖于多线程函数库
实际上,pthread_atfork这个函数并不在libpthread.so.0库里面。 是在链接的时候直接把一个.a链接到库里面的
B.so在链接的时候,使用-lpthread引入多线程库,而-lpthread并不会把包含pthread_atfork
的静态库链进来。
B.so在编译的时候 使用-pthread引入多线程库,而不是-lpthread
-lpthread和pthread的区别例如下面的代码,使用了多线程库。
#include <sys/types.h>#include <pthread.h>#include <sys/wait.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) return NULL; 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)) return NULL; } 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; }
分别采用两种方式编译成动态库
gcc -shared -fPIC -Wall -lpthread -o atfork.so main.cgcc -shared -fPIC -Wall -pthread -o atfork.so main.c
采用-lpthread生成的so大小为13008
采用-pthread生成的so大小为16816,说明链接了一块东西。。
附:如果直接用-lpthread将上段代码生成可执行程序,是会报错的,因为找不到符号。
而-pthread是不会有这种问题的。
为什么会有这种区别呢。
gcc -v -shared -fPIC -Wall -lpthread -o atfork.so main.cgcc -v -shared -fPIC -Wall -pthread -o atfork.so main.c
分别打印诊断日志。
进行比较发现。
gcc -v -shared -fPIC -Wall -pthread -o atfork.so main.c 输出 /usr/lib/gcc/x86_64-linux-gnu/5/cc1 -quiet -v -imultiarch x86_64-linux-gnu -D_REENTRANT main.c -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase main -Wall -version -fPIC -fstack-protector-strong -Wformat-security -o /tmp/cciFOaoT.s gcc -v -shared -fPIC -Wall -lpthread -o atfork.so main.c 输出 /usr/lib/gcc/x86_64-linux-gnu/5/cc1 -quiet -v -imultiarch x86_64-linux-gnu main.c -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase main -Wall -version -fPIC -fstack-protector-strong -Wformat-security -o /tmp/ccZTeFNI.s
第一个多了-D_REENTRANT, 这个宏是线程安全的意思。
转载的时候,请注明出处哦http://www.cnblogs.com/stonehat/