sem_timedwait, не поддерживаемый правильно на RedHat Enterprise Linux 5.3 вперед?

Выполните объяснять-план по каждой версии, он скажет Вам почему.

5
задан pxb 2 December 2009 в 12:18
поделиться

1 ответ

Наконец выяснил, в чем проблема. В RHEL 5.4, если мы вызываем sem_init, а затем выполняем sem_timedwait, мы получаем несколько случайное поведение синхронизированного ожидания, в зависимости от того, где расположен код, находится ли объект, которому принадлежит sem_t, в куче или стеке и т. Д. Иногда синхронизированное ожидание возвращается немедленно с errno = 38 (ENOSYS) иногда он правильно ждет перед возвратом.

Запуск его через valgrind дает следующую ошибку:

==32459== Thread 2:
==32459== Syscall param futex(op) contains uninitialised byte(s)
==32459==    at 0x406C78: sem_timedwait (in /lib/libpthread-2.5.so)
==32459==    by 0x8049F2E: TestThread::Run() (in /home/stsadm/semaphore_test/semaphore_test)
==32459==    by 0x44B2307: nxThread::_ThreadProc(void*) (in /home/stsadm/semaphore_test/libcore.so)
==32459==    by 0x4005AA: start_thread (in /lib/libpthread-2.5.so)
==32459==    by 0x355CFD: clone (in /lib/libc-2.5.so)

Если я запускаю точно такой же код в RHEL 5.2, проблема исчезает, и valgrind не сообщает об ошибках.

Если я создаю memset для переменной sem_t перед вызовом sem_init, проблема исчезнет в RHEL 5.4

memset( &_semaphore, 0, sizeof( sem_t ) );

Итак, похоже, что ошибка была внесена в семафоры в RHEL5.4 или что-то, что он использует внутри, и sem_init неправильно инициализирует память sem_t. Или, Функция sem_timed wait была изменена, чтобы быть чувствительной к этому так, как не было раньше.

Интересно, что sem_init ни в одном случае не возвращает ошибку, чтобы указать, что это не сработало.

В качестве альтернативы, если ожидаемое поведение таково, что sem_init не инициализирует память sem_t и это зависит от вызывающего, то поведение определенно изменилось с обновлением RHEL 5.4

pxb

- вот код тестового примера на случай, если кто-то еще захочет попробовать. Обратите внимание, что проблема возникает только тогда, когда sem_timedwait вызывается из .so, и только RHEL5.4 (возможно, 5.3 не тестировал его), и только когда он построен как 32-битный двоичный файл (конечно, с привязкой к 32-битным библиотекам)

1) в semtest.cpp

#include <semaphore.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>

void semtest( int semnum, bool initmem )
{
        sem_t sem;

        if ( initmem )
        {
                memset( &sem, 0, sizeof( sem_t ) );
                printf( "sem %d: memset size = %d\n", semnum, sizeof( sem_t ) );
        }

        errno = 0;
        int res = sem_init( &sem, 0, 0 );

        printf( "sem %d: sem_init res = %d, errno = %d\n", semnum, res, errno );

        timespec ts;
        clock_gettime( CLOCK_REALTIME, &ts );
        ts.tv_sec += 1;

        errno = 0;
        res = sem_timedwait( &sem, &ts );

        printf( "sem %d: sem_timedwait res = %d, errno = %d\n\n", semnum, res, errno );
}

2) в main.cpp (обратите внимание на дублирующую тестовую функцию, чтобы мы могли сравнить выполнение из .so с в exe)

#include <semaphore.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>

extern void semtest( int semnum, bool initmem );

void semtest_in_exe( int semnum, bool initmem )
{
        sem_t sem;

        if ( initmem )
        {
                memset( &sem, 0, sizeof( sem_t ) );
                printf( "sem %d: memset size = %d\n", semnum, sizeof( sem_t ) );
        }

        errno = 0;
        int res = sem_init( &sem, 0, 0 );

        printf( "sem %d: sem_init res = %d, errno = %d\n", semnum, res, errno );

        timespec ts;
        clock_gettime( CLOCK_REALTIME, &ts );
        ts.tv_sec += 1;

        errno = 0;
        res = sem_timedwait( &sem, &ts );

        printf( "sem %d: sem_timedwait res = %d, errno = %d\n\n", semnum, res, errno );
}

int main(int argc, char* argv[], char** envp)
{
        semtest( 1, false );
        semtest( 2, true );
        semtest_in_exe( 3, false );
        semtest_in_exe( 4, true );
}

3) здесь '

5
ответ дан 14 December 2019 в 04:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: