1

我想在 C 代码中获取 kernel.shmmax 的值(我使用 shell 命令“$ sysctl -q kernel.shmmax”在 centos5.0、centos6.0 和 ubuntu10.04 上查询)。

我使用以下代码找到它:

#include <sys/sysctl.h>

const int SHM_ERROR=1;

main(){
    int name[] = {KERN_SHMMAX};
    int namelen = 1;
    int oldval[1];
    size_t oldlen = sizeof(oldval);
    int rv = sysctl(name, namelen, (void*) oldval, &oldlen, NULL, 0);
    if (rv!=0) {
        fprintf(stderr, "while quering for shared memory size, sysctl returned error: %s\n", strerror(errno));
        return SHM_ERROR;
    }
    else{
        return 0;
    }
}

运行上面的代码后,我收到以下错误:

查询共享内存大小时,sysctl 返回错误:不是目录

我对为什么会收到此错误一无所知。我搜索了一下,发现库试图查看的路径存在一些问题。

我尝试使用 GDB 运行上述代码,但代码没有进入函数 sysctl,否则我可以为您提供更多信息。

数据点:我可以使用以下命令轻松地在所有提到的操作系统上从命令行设置和获取 kernel.shmmax:

$ sysctl -q kernel.shmmax

$ sysctl -w kernel.shmmax=1000000000

谢谢

4

2 回答 2

4

您不应该sysctl从用户空间代码调用。从man页面:

Glibc 没有为这个系统调用提供包装器;使用 syscall(2) 调用它。

或者更确切地说......不要调用它:长期以来一直不鼓励使用这个系统调用,而且它是如此不受欢迎,以至于它很可能在未来的内核版本中消失。立即将其从您的程序中删除;请改用 /proc/sys 接口。

所以试试这个:

#include <stdio.h>                                                                                                                  

#define SHMMAX_SYS_FILE "/proc/sys/kernel/shmmax"

int main(int argc, char **argv)
{
    unsigned int shmmax;
    FILE *f = fopen(SHMMAX_SYS_FILE, "r");

    if (!f) {
        fprintf(stderr, "Failed to open file: `%s'\n", SHMMAX_SYS_FILE);
        return 1;
    }

    if (fscanf(f, "%u", &shmmax) != 1) {
        fprintf(stderr, "Failed to read shmmax from file: `%s'\n", SHMMAX_SYS_FILE);
        fclose(f);
        return 1;
    }

    fclose(f);

    printf("shmmax: %u\n", shmmax);

    return 0;
}
于 2012-08-22T15:55:15.387 回答
1

我安装 strace 并看到 sysctl 使用 open() 调用而不是 _sysctl() 调用或 syscall() 调用查看 /proc/sys/kernel/shmmax。

于 2012-08-22T20:36:40.827 回答