문제

POSIX 세마포어에 두 개의 Slackware Linux 시스템이 있습니다. sem_open() Errno가 38로 설정된 경우 호출이 실패합니다. 아래에서 재현 할 샘플 코드 (Centos / Redhat에서 코드가 잘 작동합니다).

이를 일으킬 수있는 커널 또는 시스템 구성 옵션이 있습니까? 다른 제안?

문제가있는 시스템은 Slackware 10.1.0 Kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so입니다. 그러나 동일한 코드는 훨씬 오래된 Redhat 9 Kernel 2.4.20 /lib /librt에서 작동합니다. -2.3.2. So /lib/tls/libpthread-0.29. So. (또한 Centos 5 커널 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so에서도 작동합니다).

man sem_open 이 errno가 의미한다고 제안합니다 sem_open() 시스템에 의해 지원되지 않습니다.

#define ENOSYS          38      /* Function not implemented */

그만큼 sem_open() 사용자 공간이 있습니다 librt 우리는 역동적으로와 관련이 있습니다 librt 영향을받는 시스템에 존재합니다.

영향을받는 시스템은 Posix semaphores를 지원한다고 주장합니다. _POSIX_SEMAPHORES 사실입니다 sysconf(_SC_SEMAPHORES) 이것을 확인합니다.

고마워, 키 에란

편집 1 : 사용중인 소프트웨어 버전에 대한 자세한 내용을 추가하고 관련없는 의견을 제거했습니다.

편집 2 : /dev /shm은 우수한 시스템에 장착되며 잘못된 시스템에는 장착되지 않습니다. 마운트하면 영향을받는 시스템의 동작이 변경되지 않았습니다. /dev /shm도 필요하다고 생각하지만 Sem_open ()은 그 전에 실패하고 Strace가 이것을 지원합니다.

# /* Quick'n'dirty test program to illustrate sem_open failure
#Run this file to auto-build test and run as a.out

# Build
gcc $0 -lrt
if [ $? -ne 0 ] ; then exit ; fi

# Run
$( dirname $0)/a.out
exit
*/

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <semaphore.h>


int main(int argc, char *argv[]) {

 const char *SEM_NAME = "SHRMEM_SCXL";  /* name of mutex */
 sem_t *mutex = SEM_FAILED;             /* ptr to mutex */

#ifdef _POSIX_SEMAPHORES
  printf("_POSIX_SEMAPHORES %ld\n", _POSIX_SEMAPHORES);
#else
  puts("Undefined");
#endif

 printf("sysconf %s\n", sysconf(_SC_SEMAPHORES) ? "Yes" : "No" );

 mutex = sem_open(SEM_NAME, O_CREAT, 0666, 1);

 if (mutex == SEM_FAILED) printf("Failed %d\n", errno);
 else {
        puts("Success - pause while you check /dev/shm ");
        sleep(5);
        sem_close(mutex);
        sem_unlink(SEM_NAME);
 }
}
도움이 되었습니까?

해결책

/dev /shm가 장착되어 있습니까? 구형 버전의 Slackware는 부팅시이 파일 시스템을 장착하지 않았을 수 있습니다. /etc /fstab에서 :

tmpfs  /dev/shm  tmpfs  defaults  0   0

편집 : 아마도 그것은 아마도 문제가 아닐 것입니다. 나는 당신이 당신의 커널이나 심지어 librt를 업그레이드해야 할 수도 있다고 생각합니다.

edit2 : 사용중인 Slackware 11의 경우 SEM_OPEN이 필요한 것으로 보이는 NPTL 스레딩 라이브러리 (LIBS /LIB /TLS)를 사용하려면 2.6.13보다 새로 커널이 필요하다고 생각합니다. 일하다.

edit3 : a) 마운팅 /데브 /SHM 및 b) 환경 변수 설정 LD_ASSUME_KERNEL 2.6.13까지 (모든 커널 버전> 2.6.12가 작동합니다). 커널이 2.6.11.11이지만 작동하는 것처럼 보이지만 스레드와 같은 다른 것들은 그렇지 않을 수 있습니다.

다른 팁

구형 버전의 스레딩 라이브러리는 프로세스간에 posix 세마포어를 공유하는 것을 지원하지 않습니다. 에서 man sem_init

Pshared 인수는 세마포어가 현재 프로세스에 국한되는지 (Pshared는 0) 또는 여러 프로세스간에 공유 될지 여부를 나타냅니다 (Pshared는 0이 아님). Linuxthreads는 현재 프로세스 공유 세마포어를 지원하지 않으므로 Pshared가 0이 아닌 경우 Sem_init은 항상 Error Enosys로 반환됩니다.

sem_open ()이 세마포어라는 이름을 만들기 때문에 항상 프로세스간에 공유하려고합니다.

Slackware 10에서 Sem_Init ()를 사용한 프로세스간에 익명의 세마포어 공유를 지원합니다.

  • libpthread 및 (아마도) librt를 업그레이드하십시오
  • 커널을 업그레이드하십시오

또한 sem_open ()와 Semaphores라는 공유를 지원합니다.

  • 라인을 추가하십시오 /etc/fstab 마운트 /dev/shm TMPF로

    tmpfs /dev /shm tmpfs 기본값 0 0

  • 운영 mount /dev/shm 또는 재부팅

"프로세스 공유 SEMA4는 작동하지 않습니다"가설은 나에게 의미가 있습니다. 그것이 당신에게 도움이되지는 않지만, 시간과 성향이 있다면 다음을 시도해 볼 수 있습니다. "프로세스 공유"측면이 실패한 지 확인하십시오.

  1. 공유 메모리에서 SEM_INIT를 사용하여 세마포어를 만듭니다 (스레드 용). 그것이 작동하면 SEMA4는 프로세스 내에서 작동합니다.

  2. 공유 메모리에서 실험을 반복하십시오. 프로세스간에 작동하는지 알려야합니다. 실제로 SEMA4를 사용하여 프로세스간에 작동하는지 확인해야 할 수도 있습니다.

프로세스에서 세마포어를 공유하는 또 다른 방법은 SystemV 세마포어를 사용하는 것입니다.

이것들은 공유 된 posix semaphores가하지 않는 경우에도 작동합니다 (적어도 위에서 설명한 시스템에서).

보다 http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html 두 가지 유형의 세마포어 사용의 예.

나는 posix 메시지 대기열로 작업하고 있었다. 나는 Errono 38 (enosys)에서 mq_open이 실패한 것과 동일한 오류를 얻었다.

이 작업은 커널 구성에서 Posix Messge 대기열을 사용하여 Kenel을 재건하는 것입니다.

이것은 Posix Message Queue 지원으로 커널을 구축 할 것이며 저에게 효과적이었습니다.

감사

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top