首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何停止sem_open()失败?

如何停止sem_open()失败?
EN

Stack Overflow用户
提问于 2008-11-07 04:25:18
回答 5查看 12.6K关注 0票数 3

我有两个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()

代码语言:javascript
复制
#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支持这一点。

代码语言:javascript
复制
# /* 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);
 }
}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2008-11-06 21:33:38

/dev/shm是否已挂载?旧版本的松散软件可能没有在引导时挂载此文件系统。从/etc/fstab:

代码语言:javascript
复制
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,但这似乎可以工作,但线程等其他功能可能就不行了。

票数 5
EN

Stack Overflow用户

发布于 2008-11-07 12:20:20

旧版本的线程库不支持在进程之间共享POSIX信号量。来自man sem_init

参数pshared表示信号量是当前进程本地的( pshared为零),还是在多个进程之间共享( pshared不为零)。LinuxThreads目前不支持进程共享信号量,因此如果pshared不为零,sem_init总是返回错误ENOSYS。

当sem_open()创建命名信号量时,它总是尝试在进程之间共享它们。

为了支持在Slackware10上使用sem_init()在进程之间共享匿名信号量

  • 升级libpthread和(可能)
  • 升级内核

此外,为了支持与sem_open()共享命名信号量

  • 将一行添加到/etc/fstab以将/dev/shm挂载为tmpfs

tmpfs /dev/shm tmpfs默认值0 0

  • 运行mount /dev/shm或重新启动
票数 1
EN

Stack Overflow用户

发布于 2008-11-07 16:15:06

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

  1. 在非共享内存(用于线程)中使用sem_init创建信号量。如果它可以工作,那么在共享内存中的process.
  2. repeat实验中,sema4s就可以工作。这应该会告诉您它们是否在进程之间工作。请注意,您可能需要实际尝试使用sema4,以查看它在进程之间是否工作。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/270113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档