2011-11-07 70 views
1

我已经写了一些代码,它在linux下编译得很好,但是在Solaris上我有一些编译错误。我用gcc test_compile.c -o tes -pthreads来编译。无法在Solaris下使用信号编译代码?

#include <semaphore.h> 

int main(){ 
    sem_t semaphore; 
    sem_init(&semaphore, 0, 0); 
    return 0; 
} 

给我

itchy:~/edu/sysprog> gcc test_compile.c -o tes -pthreads 
Undefined      first referenced 
symbol        in file 
sem_init       /var/tmp//ccUiSK6A.o 
ld: fatal: Symbol referencing errors. No output written to tes 

我不知道发生了什么事情。我尝试用sema_init替换sem_init,并编译(看到在线的某处)。但是这意味着我必须通过我的整个代码并用sema替换sem。没有更简单的解决方案吗?它是什么意思?

+2

你得到一个编译时错误,但它是不是编译器错误。不幸的是,“编译”这个词已经被用来表示“构建一个可执行文件”,但是两者不一样。你的问题是链接器。 –

回答

3

您需要具有实时扩展库librt链接:

gcc test_compile.c -o tes -lrt -pthreads 

这在手册页中为sem_init(3RT)

SYNOPSIS 
    cc [ flag... ] file... -lrt [ library... ] 
    #include <semaphore.h> 

    int sem_init(sem_t *sem, int pshared, unsigned int value); 
+0

我不确定这是否属实。 [此手册页](http://linux.die。net/man/3/sem_init)似乎表明你需要用'pthreads'或'lrt'链接。与pthreads链接最有意义(imo)。 – jedwards

+0

您链接到一个Linux手册页。 我引用了上面的Solaris手册页,并在Solaris 10上对其进行了测试。从某种意义上说,您没有_need_'-pthreads'来在Solaris上启用'sem_init',但同时它不应该做任何伤害(二进制大24字节!)。 –

+0

那么它是'-pthreads'还是'-lpthreads'?对不起,我没有环境来测试它。 – Deqing

2

在做完所有这些之前,我首先要确保您链接正确。它似乎编译好,但在连接步骤失败。所以首先确保你实际上有semaphore.h,它包括sem_init(...)。如果你这样做,我的猜测是你做的,检查你的编译命令。如果这是您的问题中的编译命令,请尝试将-lpthread添加到您的编译行以链接到posix线程库。


所以,你应该仔细检查SEMA你想要做什么,因为他们是不同的库 - sem是从POSIX pthreads库和sema是从Solaris thread库。 (See this also)但是,如果它们与代码兼容,并且如果您在寻找跨平台兼容的代码,那么您可能需要执行一些操作,例如创建简单的包装函数,然后有条件地包含它。

您的包装函数非常简单,接受相同的类型并返回相同的类型,例如

ret_type sem_init(argtype arg1, argtype arg2, argtype arg3) 
{ 
    return sema_init(arg1, arg2, arg3) 
} 

然后有条件地包括它的东西,如

#ifdef SOLARIS 
#include semaphore_wrappers.h 
#endif 

注意,SOLARIS是不会被定义。在solaris上编译时,您必须手动编写#define SOLARIS,或者在编译命令行/ makefile中定义它。

至少这是我该怎么做。

需要注意的是,如果这是是跨平台兼容的,它更容易阅读和调试,如果你只是做一个全局搜索和替换。

+1

注意:链接'-lpthreads'应该可以解决问题。其他人在其他地方也有类似的问题:http://www.linuxforums.org/forum/programming-scripting/33643-linker-error-undefined-reference-sem_init.html – jedwards