Не можете скомпилировать код с семафором под Solaris?

Я написал некоторый код, который отлично компилируется под 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_init на sema_init, и он скомпилировался (видел это где-то в Интернете). Однако это означало бы, что я должен просмотреть весь свой код и заменить sem на sema. Нет ли более простого решения? И что это на самом деле означает?


person Pithikos    schedule 07.11.2011    source источник
comment
Вы получаете ошибку времени сборки, но это не ошибка компилятора. К сожалению, слово «компилировать» используется для обозначения сборки исполняемого файла, но это не одно и то же. Ваша проблема связана с линкером.   -  person William Pursell    schedule 07.11.2011


Ответы (2)


Вам нужно связать с библиотекой расширений реального времени 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);
person Martin Carpenter    schedule 07.11.2011
comment
Я не уверен, что это правда. Эта справочная страница, по-видимому, указывает, что вам нужно установить связь с pthreads или lrt. Связывание с pthreads имеет наибольший смысл (imo). - person jedwards; 07.11.2011
comment
Вы ссылаетесь на справочную страницу Linux. Я процитировал справочную страницу Solaris выше и протестировал ее на Solaris 10. Вы правы в том смысле, что вам не нужно -pthreads включать sem_init в Solaris, но в то же время это не должно навредить (двоичный файл больше на 24 байта!). - person Martin Carpenter; 07.11.2011
comment
Так это -pthreads или -lpthreads? Извините, у меня пока нет среды для тестирования. - person Deqing; 05.10.2014
comment
-pthreads для старых версий gcc, -lpthreads для новых версий - person Martin Carpenter; 29.11.2014

Перед всем этим я бы сначала убедился, что вы правильно связываетесь. Кажется, что скомпилировано нормально, но не удалось на этапе компоновки. Поэтому сначала убедитесь, что у вас действительно есть semaphore.h и что он включает sem_init(...). Если вы это сделаете, а я предполагаю, что вы это сделаете, проверьте свою команду компиляции. Если это ваша команда компиляции в вашем вопросе, попробуйте добавить -lpthread в строку компиляции, чтобы связать ее с библиотекой потоков posix.


Таким образом, вы должны дважды проверить, что sema делает то, что вы хотите, поскольку это разные библиотеки - sem из библиотеки pthreads POSIX, а sema из библиотеки thread Solaris. (см. также) Но если они совместимы по коду, и если вы ищете кросс-платформенный совместимый код, вы, вероятно, захотите сделать что-то вроде создания простых функций-оболочек, а затем условно включить их.

Ваши функции-оболочки будут очень простыми, будут принимать одни и те же типы и возвращать один и тот же тип, например.

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

А затем условно включить его с чем-то вроде

#ifdef SOLARIS
#include semaphore_wrappers.h
#endif

Обратите внимание, что SOLARIS не будет определен. Вам придется либо вручную #define SOLARIS компилировать на Solaris, либо определить это в вашей командной строке компиляции / makefile.

По крайней мере, я бы так поступил.

Обратите внимание, что если это не для кросс-платформенной совместимости, его будет намного проще читать и отлаживать, если вы просто выполните глобальный поиск и замену.

person jedwards    schedule 07.11.2011
comment
Примечание: связывание с -lpthreads должно решить проблему. У других были подобные вопросы в другом месте: linuxforums .org/forum/programming-scripting/ - person jedwards; 07.11.2011