【问题标题】:Find the maximum number of semaphores that one process can have open at a time查找一个进程一次可以打开的最大信号量
【发布时间】:2018-10-10 21:28:35
【问题描述】:

要找到一个进程一次可以打开的最大信号量,我不明白为什么下面的代码_SC_SEM_NSEMS_MAX 返回-1

int main(void) {
        long max_limit = 0;
        errno = EINVAL;
        max_limit = sysconf(_SC_SEM_NSEMS_MAX);
        printf("max_limit : %ld error_no : %d\n",max_limit,errno);

        return 0;
} 

编辑:-这是我尝试手动获取最大限制的内容。

struct count {
        sem_t sem_addr;
        int count;
};
int main(void) {
        int fd = 0,zero = 0;
        struct count *shared;
        fd = shm_open("/my_semaphore",O_RDWR|O_CREAT,0777);
        if(fd == -1){
                perror("shm_open");
                exit(0);
        }
        //ftruncate(fd,4096);
        write(fd,&zero,4);
        shared = mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(off_t)0);
        sem_init(&shared->sem_addr,1,1);

        pid_t pid = fork();
        if(pid > 0) {
                //printf("parent process: %d \n",getpid());
                sem_wait(&shared->sem_addr);
                for(int i = 0;i < 50 ;i++) {
                        printf("parent = %d \n",shared->count++);
                }
                sem_post(&shared->sem_addr);
        }
        else if (pid == 0) {
                //printf("child process: %d \n",getpid());
                sem_wait(&shared->sem_addr);
                for(int i = 0;i < 50 ;i++) {
                        printf("child = %d \n",shared->count++);
                }
                sem_post(&shared->sem_addr);
        }
        sem_destroy(&shared->sem_addr);
        return 0;
}

任何帮助将不胜感激。

【问题讨论】:

  • 在调用sysconf之前设置errno为0,之后检查。
  • @MatteoItalia 有没有最大限制?我检查了ipcs -l,它没有说明一个进程一次可以拥有的最大信号量

标签: c linux posix semaphore


【解决方案1】:
long sysconf(int name );

返回名称指定的限制值, 如果限制不确定或发生错误,则为 –1。

如果无法确定限制,sysconf() 将返回 –1。如果发生错误,它也可能返回 –1。 (唯一指定的错误是 EINVAL ,表示名称无效。)为了区分不确定限制的情况和错误,我们必须在调用之前将 errno 设置为零;如果调用返回 –1 并且在调用之后设置了 errno,则发生错误,否则限制是不确定的。

在您的情况下,它不是错误,而是无法确定限制。

#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
extern errno ;
int main()
{
    errno = 0;
    long max_limit = 0;
    max_limit = sysconf(_SC_SEM_NSEMS_MAX);
    printf("%ld\n", max_limit);
    printf("err msg: %m\n");
    return 0;
}  

输出:
-1
错误消息:成功

【讨论】:

    【解决方案2】:

    来自手册页:

    RETURN VALUE
           If name is invalid, -1 is returned, and errno is set to EINVAL.  Other‐
           wise, the value returned is the value of the system resource and errno
           is  not  changed.  In the case of options, a positive value is returned
           if a queried option is available, and -1 if it is not.  In the case  of
           limits, -1 means that there is no definite limit.
    

    特别注意最后一句话。因此,-1 可能意味着您的系统不知道 _SC_SEM_NSEMS_MAX 或者没有限制。无论哪种方式,我都将其解释为开放信号量的最大数量不受系统任意限制(当然它可能受到内存限制等限制)。

    【讨论】:

    • 感谢您的解释。 -1 可能意味着您的系统不知道 _SC_SEM_NSEMS_MAX ?您是说 POSIX 不支持它。
    【解决方案3】:

    也许你应该检查一下errno?

       The return value of sysconf() is one of the following:
    
       *  On error, -1 is returned and errno is set to indicate the cause of
          the error (for example, EINVAL, indicating that name is invalid).
    
       *  If name corresponds to a maximum or minimum limit, and that limit
          is indeterminate, -1 is returned and errno is not changed.  (To
          distinguish an indeterminate limit from an error, set errno to
          zero before the call, and then check whether errno is nonzero when
          -1 is returned.)
    
       *  If name corresponds to an option, a positive value is returned if
          the option is supported, and -1 is returned if the option is not
          supported.
    

    【讨论】:

      猜你喜欢
      • 2012-03-02
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多