我有两个Slackware Linux系统,POSIX信号量sem_open()
调用失败,errno设置为38.示例代码重现如下(代码在CentOS / RedHat上正常工作)。
是否有可能导致此问题的内核或系统配置选项?其他建议?
有问题的系统是Slackware 10.1.0内核2.6.11 /lib/librt-2.3.4.so /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);
}
}
答案 0 :(得分:5)
是/ 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,这似乎也可行,但其他类似线程的东西可能不会。
答案 1 :(得分:1)
较旧版本的线程库不支持在进程之间共享POSIX信号量。来自man sem_init
pshared参数指示信号量是否是本地信号量 当前进程(pshared为零)或将在几个之间共享 进程(pshared不为零)。 LinuxThreads目前没有 支持进程共享信号量,因此sem_init总是返回 如果pshared不为零,则出现错误ENOSYS。
当sem_open()创建命名信号量时,它总是尝试在进程之间共享它们。
支持在Slackware 10上使用sem_init()在进程之间共享匿名信号量
此外,支持使用sem_open()
共享命名信号量在/etc/fstab
添加一行以挂载/dev/shm
作为tmpfs
tmpfs / dev / shm tmpfs defaults 0 0
运行mount /dev/shm
或重新启动
答案 2 :(得分:1)
“进程共享sema4s不起作用”假设对我有意义。并不是它对你有帮助,但如果你有时间和倾向,你可能想尝试以下方法,看看“进程共享”方面是否失败:
在非共享内存中使用sem_init创建信号量(对于线程)。如果它有效,则sema4s在该过程中工作。
在共享内存中重复实验。这应该告诉您它们是否在进程之间工作。请注意,您可能需要实际尝试使用sema4来查看它是否在进程之间起作用。
答案 3 :(得分:0)
跨进程共享信号量的另一种方法是使用SystemV信号量。
即使共享POSIX信号量没有(至少在上述系统上),它们也能工作。
有关两种信号量使用的示例,请参阅http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html。
答案 4 :(得分:0)
我正在使用posix消息队列我有同样的错误mq_open失败了errono 38(ENOSYS)。
工作重点是在内核配置中启用POSIX MESSGE QUEUE来重建kenel。
这将构建具有POSIX消息队列支持的内核,它对我有用。
由于