1

我编写了一些在 linux 下编译良好的代码,但在 Solaris 上我得到了一些编译错误。我gcc test_compile.c -o tes -pthreads用来编译。

#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

我不确定发生了什么。我尝试替换sem_initsema_init并编译(在网上某处看到)。但是,这意味着我必须检查整个代码并将 sem 替换为 sema。没有更简单的解决方案吗?它的真正含义是什么?

4

2 回答 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);
于 2011-11-07T11:33:53.420 回答
2

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


因此,您应该仔细检查 sema 是否符合您的要求,因为它们是不同sem的库——来自 POSIXpthreads库和sema来自 solaristhread库。(另请参阅)但是如果它们是代码兼容的,并且如果您正在寻找跨平台兼容的代码,您可能想要做一些事情,例如创建简单的包装函数,然后有条件地包含它。

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

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 中定义它。

至少我会这样做。

请注意,如果这不是跨平台兼容的,那么如果您只是进行全局搜索和替换,那么阅读和调试会容易得多。

于 2011-11-07T11:16:33.257 回答