我有两个Slackware Linux系统,它们的POSIX信号量sem_open()调用失败,errno设置为38。重现下面的示例代码(该代码在CentOS /RedHat上运行良好)。
是否有任何内核或系统配置选项可能导致此问题?还有其他建议吗?
有问题的系统是Slackware 10.1.0内核2.6.11 /lib/librt 2.3.4.so/lib /lib/libpthread-0.10.so,但相同的代码可以在更老的RedHat 9内核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建议此错误号表示系统不支持sem_open()。
#define ENOSYS 38 /* Function not implemented */sem_open()用户空间位于我们动态链接的librt中,而librt位于受影响的系统上。
受影响的系统声称支持POSIX信号量:_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);
}
}发布于 2008-11-06 21:33:38
/dev/shm是否已挂载?旧版本的松散软件可能没有在引导时挂载此文件系统。从/etc/fstab:
tmpfs /dev/shm tmpfs defaults 0 0编辑:这可能不是问题所在。我认为你可能只需要升级你的内核,或者甚至是librt。
Edit2:我认为对于您正在使用的slackware 11,您需要一个比2.6.13更高的内核来使用NPTL线程库(/lib/tls中的库),这似乎是sem_open工作所必需的。
Edit3:我通过a)挂载/dev/shm和b)将环境变量LD_ASSUME_KERNEL设置为2.6.13 (任何高于2.6.12的内核版本都可以),成功地让它在我的一个松散软件11机器上工作。尽管内核是2.6.11.11,但这似乎可以工作,但线程等其他功能可能就不行了。
发布于 2008-11-07 12:20:20
旧版本的线程库不支持在进程之间共享POSIX信号量。来自man sem_init
参数pshared表示信号量是当前进程本地的( pshared为零),还是在多个进程之间共享( pshared不为零)。LinuxThreads目前不支持进程共享信号量,因此如果pshared不为零,sem_init总是返回错误ENOSYS。
当sem_open()创建命名信号量时,它总是尝试在进程之间共享它们。
为了支持在Slackware10上使用sem_init()在进程之间共享匿名信号量
此外,为了支持与sem_open()共享命名信号量
/etc/fstab以将/dev/shm挂载为tmpfstmpfs /dev/shm tmpfs默认值0 0
mount /dev/shm或重新启动发布于 2008-11-07 16:15:06
“进程共享sema4s不工作”的假设对我来说是有意义的。这并不是说它对你有帮助,但是如果你有时间和兴趣,你可能会想尝试以下方法,看看“进程共享”方面是否失败了:
https://stackoverflow.com/questions/270113
复制相似问题