我有两个要多得多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 作为一个tmpfs

    tmpfs/dev/shm tmpfs违约0 0

  • 运行 mount /dev/shm 或重新启动

“进程共享sema4s不起作用”假设对我有意义。并不是说它对你有所帮助,但是如果你有时间和倾向,你可能想尝试以下方法,看看是否“进程共享”了。方面是失败的:

  1. 在非共享内存中使用sem_init创建信号量(对于线程)。如果它有效,则sema4s在该过程中工作。

  2. 在共享内存中重复实验。这应该告诉您它们是否在进程之间工作。请注意,您可能需要实际尝试使用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消息队列支持的内核,它对我有用。

由于

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top