我如何阻止sem_open()未能与ENOSYS?
题
我有两个要多得多Linux系统POSIX信号 sem_open()
呼叫失败errno落至38个。样本代码如下(代码的工作现在CentOS/RedHat).
是否有任何核心或系统结构的选项,可能导致这个?其他建议吗?
系统问题的要多得多10.1.0核2.6.11/lib/librt-2.3.4.因此/lib/libpthread-0.10.所以,但是同样的代码工作上的很多老年RedHat9核2.4.20/lib/librt-2.3.2.因此/lib/tls/libpthread-0.29.此。(并且也适用于CentOS5的核2.6.18/lib/librt-2.5.因此/lib/i686/nosegneg/libpthread-2.5.如此)。
man sem_open
表明这errno装置 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);
}
}
解决方案
是/ dev / shm安装?较旧版本的slackware可能没有在启动时挂载此文件系统。来自/ etc / fstab:
tmpfs /dev/shm tmpfs defaults 0 0
编辑:毕竟这可能不是问题。我想你可能只需要升级你的内核,甚至可能需要librt。
Edit2:我认为对于我认为你正在使用的slackware 11,你需要一个比2.6.13更新的内核来使用NPTL线程库(/ lib / tls中的库),它们似乎是sem_open工作。
Edit3:我设法让它与slackware 11盒子一起使用a)mount / dev / shm和b)将环境变量 LD_ASSUME_KERNEL
设置为2.6.13(任何内核版本) &gt; 2.6.12将起作用)。即使内核是2.6.11.11,这似乎也可行,但其他类似线程的东西可能不会。
其他提示
旧版本的线图书馆不要支持分享POSIX信号灯之间的进程。从 man sem_init
该pshared说法是否指示信号是本地的 目前的进程(pshared为零)或是之间共享数 进程(pshared不是零)。LinuxThreads目前不会 支持过程中共享信号,因此sem_init总是返回 错误ENOSYS如果pshared不是零。
作为sem_open()创建了名为的信号,总是试图分享它们之间的进程。
支持分享匿名信号灯之间的进程与sem_init()上要多得多10
- 升级libpthread和(可能的)librt
- 升级的内核
此外,为支持分享叫信号与sem_open()
添加一条线
/etc/fstab
山/dev/shm
作为一个tmpfstmpfs/dev/shm tmpfs违约0 0
运行
mount /dev/shm
或重新启动
“进程共享sema4s不起作用”假设对我有意义。并不是说它对你有所帮助,但是如果你有时间和倾向,你可能想尝试以下方法,看看是否“进程共享”了。方面是失败的:
-
在非共享内存中使用sem_init创建信号量(对于线程)。如果它有效,则sema4s在该过程中工作。
-
在共享内存中重复实验。这应该告诉您它们是否在进程之间工作。请注意,您可能需要实际尝试使用sema4来查看它是否在进程之间起作用。
醇>
跨进程共享信号量的另一种方法是使用SystemV信号量。
即使共享POSIX信号量没有(至少在上述系统上),它们也能工作。
请参阅 http:// www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html 了解两种信号量使用的示例。
我正在使用posix消息队列我有同样的错误mq_open失败了errono 38(ENOSYS)。
工作重点是在内核配置中启用POSIX MESSGE QUEUE来重建kenel。
这将构建具有POSIX消息队列支持的内核,它对我有用。
由于