实验环境介绍
- gcc:4.8.5
- glibc:glibc-2.17-222.el7.x86_64
- os:Centos7.4
- kernel:3.10.0-693.21.1.el7.x86_64
引言
- 略过
Unix标准化
- 都是历史,略过
Unix系统实现
- 都是历史,略过
标准与实现的差异
- 略过
限制
unix限制
- 必需的两种限制:
- 编译时限制(例如:短整型的最大值)
- 运行时限制(例如:文件名有多少字符)
- 编译时限制的解决方案:头文件
- 运行时限制的解决方案 :
- 与文件和目录无关的运行时限制:sysconf函数
- 与文件或目录有关的运行时限制:pathconf和fpathconf函数
后面说明
ISO C限制
在limit.h中,如下图:
测试代码如下:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
printf("CHAR_BIT: %d\n", CHAR_BIT);
printf("CHAR_MAX: %d\n", CHAR_MAX);
printf("CHAR_MIN: %d\n", CHAR_MIN);
printf("INT_MAX: %d\n", INT_MAX);
printf("INT_MIN: %d\n", INT_MIN);
exit(EXIT_SUCCESS);
}
result:
CHAR_BIT: 8
CHAR_MAX: 127
CHAR_MIN: -128
INT_MAX: 2147483647
INT_MIN: -2147483648
POSIX限制
- posix.1定义了很多设计操作系统实现限制的常量,我们只关心与基本posix.1接口有关的部分。这些限制和常量分为下列7类:
- 数值限制:LOG_BIT、SSIZE_MAX和WORD_BIT
- 最小值:如下图,这些最小值并不随系统而改变。(忽略名字中的max)
- 最大值:_POSIX_CLOCKRES_MIN
- 运行时可以增加的值:CHARCLASS_NAME_MAX、COLL_WEIGHTS_MAX、LINE_MAX、NGROUPS_MAX和RE_DUP_MAX
- 运行时不变值:如下图等
- 其他不变值:NL_ARGMAX、NL_MSGMAX、NL_SSETMAX和NL_TEXTMAX
- 路径名可变值:FILESIZEBITS、LINK_MAX、MAX_CANON、MAX_INPUT、NAME_MAX、PATH_MAX、PIPE_BUF和SYMLINK_MAX
某些变量可能没有在
XSI限制
- XSI定义了代表实现限制的几个常量
- 最小值:如下图
- 运行时不变值(可能不确定):IOV_MAX和PAGE_SIZE
- 最小值:如下图
函数sysconf、pathconf和fpathconf
sysconf的限制及其参数如下图
测试代码如下
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ONE_MB (1024 * 1024)
int
main(int argc, char *argv[])
{
// test sysconf
printf("The number of processors configured is :%ld\n",
sysconf(_SC_NPROCESSORS_CONF));
printf("The number of processors currently online (available) is :%ld\n",
sysconf(_SC_NPROCESSORS_ONLN));
printf ("The pagesize: %ld\n", sysconf(_SC_PAGESIZE));
printf ("The number of pages: %ld\n", sysconf(_SC_PHYS_PAGES));
printf ("The number of available pages: %ld\n", sysconf(_SC_AVPHYS_PAGES));
printf ("The memory size: %lld MB\n",
(long long)sysconf(_SC_PAGESIZE) * (long long)sysconf(_SC_PHYS_PAGES) / ONE_MB );
printf ("The number of files max opened:: %ld\n", sysconf(_SC_OPEN_MAX));
printf("The number of ticks per second: %ld\n", sysconf(_SC_CLK_TCK));
printf ("The max length of host name: %ld\n", sysconf(_SC_HOST_NAME_MAX));
printf ("The max length of login name: %ld\n", sysconf(_SC_LOGIN_NAME_MAX));
// test pathconf
char pathname[] = "/home";
printf("NAME_MAX = %ld\n", pathconf(pathname, _PC_NAME_MAX));
printf("PATH_MAX = %ld\n", pathconf(pathname, _PC_PATH_MAX));
printf("LINK_MAX = %ld\n", pathconf(pathname, _PC_LINK_MAX));
printf("MAX_INPUT = %ld\n", pathconf(pathname, _PC_MAX_INPUT));
printf("MAX_CANON = %ld\n", pathconf(pathname, _PC_MAX_CANON));
printf("PIPE_BUF = %ld\n", pathconf(pathname, _PC_PIPE_BUF));
// test fpathconf
int files = open(pathname, O_RDONLY);
printf("NAME_MAX = %ld\n", fpathconf(files, _PC_NAME_MAX));
printf("PATH_MAX = %ld\n", fpathconf(files, _PC_PATH_MAX));
printf("LINK_MAX = %ld\n", fpathconf(files, _PC_LINK_MAX));
printf("MAX_INPUT = %ld\n", fpathconf(files, _PC_MAX_INPUT));
printf("MAX_CANON = %ld\n", fpathconf(files, _PC_MAX_CANON));
printf("PIPE_BUF = %ld\n", fpathconf(files, _PC_PIPE_BUF));
exit(EXIT_SUCCESS);
}
result:
The number of processors configured is :2
The number of processors currently online (available) is :2
The pagesize: 4096
The number of pages: 249657
The number of available pages: 35592
The memory size: 975 MB
The number of files max opened:: 1024
The number of ticks per second: 100
The max length of host name: 64
The max length of login name: 256
NAME_MAX = 255
PATH_MAX = 4096
LINK_MAX = 2147483647
MAX_INPUT = 255
MAX_CANON = 255
PIPE_BUF = 4096
NAME_MAX = 255
PATH_MAX = 4096
LINK_MAX = 2147483647
MAX_INPUT = 255
MAX_CANON = 255
PIPE_BUF = 4096
- pathconf和fpathconf的限制及name参数如下图
不确定的运行时限制
- 前面说的某些限制值可能是不确定的。如果没有在
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#ifdef PATH_MAX
static long pathmax = PATH_MAX;
#else
static long pathmax = 0;
#endif
static long posix_version = 0;
static long xsi_version = 0;
#define PATH_MAX_GUESS 1024
char *
path_alloc(size_t *sizep)
{
char *ptr;
size_t size;
if (!posix_version)
posix_version = sysconf(_SC_VERSION);
if (!xsi_version)
xsi_version = sysconf(_SC_XOPEN_VERSION);
if (!pathmax) {
errno = 0;
if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0) {
int errno_save = errno;
if (errno_save == 0)
pathmax = PATH_MAX_GUESS;
else
perror("pathconf error for _PC_PATH_MAX:");
} else
pathmax++;
}
if ((posix_version < 200112L) && (xsi_version < 4))
size = pathmax + 1;
else
size = pathmax;
if ((ptr = malloc(size)) == NULL)
perror("malloc error for pathname");
if (sizep)
*sizep = size;
return (ptr);
}
int
main(int argc, char *argv[])
{
size_t size;
char *ptr = path_alloc(&size);
if (ptr)
printf("alloc size = %zu successfully\n", size);
else
printf("alloc failed\n");
exit(EXIT_SUCCESS);
}
result:
[root@localhost part_2]# ./2_16
alloc size = 4096 successfully
- 最大打开文件数:使用POSIX.1的OPEN_MAX来提高移植性
- 测试代码如下
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#ifdef OPEN_MAX
static long openmax = OPEN_MAX;
#else
static long openmax = 0;
#endif
#define OPEN_MAX_GUESS 256
long
open_max(void)
{
if (!openmax) {
errno = 0;
if ((openmax = sysconf(_SC_OPEN_MAX)) < 0) {
if (!errno)
openmax = OPEN_MAX_GUESS;
else
perror("sysconf error for _SC_OPEN_MAX");
}
}
return (openmax);
}
int
main(int argc, char *argv[])
{
long openmax = open_max();
if (openmax < 0)
printf("open_max get error\n");
else
printf("openmax is: %ld\n", openmax);
exit(EXIT_SUCCESS);
}
result:
[root@localhost part_2]# ./2_17
openmax is: 1024
选项
- 如同对限制的处理一样,posix.1定义了3种处理选项的方法
- 编译时选项定义在
功能测试宏
- 忽略
基本系统数据类型
头文件中定义了某些与实现有关的数据类型。绝大多数都是以_t结尾,用这种方式定义这些数据类型后,就不再需要考虑因系统不同而变化的程序实现细节
如下图
标准之间的冲突
ISO C定义了clock函数,返回进程使用的cpu时间,返回值是clock_t类型值,单ISO C没有规定他的单位。为了将值转换成以秒为单位,需要将其除以在