如何确定 pid_t
类型的最大值,使其具有可移植性?我的系统上没有 PID_MAX 常量。
(注意,我指的是数据类型允许的最大值,而不是系统将分配给进程的实际最大值。)
用例:我正在将用户提供的字符串规范转换为 pid_t
,并希望确保用户的输入不超过该类型的容量。
过去我有时使用更大的数据类型,然后当我转换为较小的类型时,立即将其转换回更大的类型并检查值是否发生变化。
例如,如果您使用int64_t,则可能会有类似以下的代码:
int64_t my_pid64;
/* ... parse string value into my_pid64 ... */
pid_t my_pid = (pid_t) my_pid64;
if ((int64_t) my_pid != my_pid64) /* check that value was not out of range of pid_t */
{
/* ... handle error ... */
}
没有很好的选项来使用更大的数据类型。 "long"曾经是最大的原始整数数据类型,但在一些常见的编译器/体系结构上不再是真实的情况-即使对于Linux(请参见下面的评论)。 同时,intmax_t类型具有较差的库支持。 结果是,在实践中int64_t有时更有用。
但是,基本上您可以选择使用long、int64_t和intmax_t这些更大的数据类型。
long long
相同大小,尽管级别较低),但不适用于x86的Linux(与int
相同大小,小于long long
)。 - Steve JessopSteven的回答是一个好方法。
但是如果你真的想确定最大的pid_t
值而不依赖于未定义的行为,我认为你最好的选择是:
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
static inline pid_t get_max_pid_t()
{
if (sizeof(pid_t) == sizeof(short)) return SHRT_MAX;
if (sizeof(pid_t) == sizeof(int)) return INT_MAX;
if (sizeof(pid_t) == sizeof(long)) return LONG_MAX;
#if defined(LLONG_MAX) // C99
if (sizeof(pid_t) == sizeof(long long)) return LLONG_MAX;
#endif
abort();
}
POSIX保证pid_t
是有符号整型。此代码假定有符号整型的大小唯一确定该类型。我认为这是一个很好的假设,但我不确定标准是否保证它。
任何合理的编译器都会将所有内容内联和常量传播到不存在状态,因此性能不是问题。
(顺便说一句,在C++中,您可以编写std::numeric_limits<pid_t>::max()
并完成它。)
POSIX (2008)规定:
blksize_t、pid_t和ssize_t应该是带符号整数类型。
并且:
实现应支持一个或多个编程环境,其中blksize_t、pid_t、size_t、ssize_t和suseconds_t的宽度不大于long类型的宽度。
因此,您可以将用户字符串转换为long
,然后使用long pid; .. pid == (pid_t)pid
检查pid_t类型的溢出。
在你的头文件中的其中一个:
#ifndef PID_MAX
#define PID_MAX INT_MAX // or whatever value you see fit
#endif
你也可以根据环境变量基于服务器/操作系统相关的定义来完成它。
看一下: 类似文章:Linux中的最大PID
pid_t
是一个int
而不是一个long
。另外,我认为那篇链接的帖子与此无关:我想要的是数据类型的最大值,而不是系统将分配的最大值(可能会更低)。 - pilcrow
sizeof
不足以满足您的目的吗?(我不确定为什么您需要它,能否详细说明一下?) - Mat/proc/sys/kernel/pid_max
定义了最大的 pid,您可以进行编辑。 - P.P#define PID_MAX ((1 << sizeof(pid_t)) - 1)
? 或者如果不能保证是无符号的,#define PID_MAX ((1 << (sizeof(pid_t) - 1)) - 1)
。 - Shahbazpid_t
是对int
的typedef
。因此,您可以将PID_MAX
宏定义为#define PID_MAX INT_MAX
。 - Jack