信号用于向进程或线程通知特定事件。Linux 支持 POSIX 标准信号和 POSIX 实时信号。每个信号都有惟一名称和相应的信号编号。例如,对于 Solaris,SIGSTOP 的信号编号是 23,但是对于 Linux on POWER,其信号编号则为 19。/usr/include/bits/signum 中可以找到 Linux 上的信号编号定义。
对于所有可能的信号,系统会定义出现信号时执行的默认操作:
- Terminate:默认操作是终止进程。
- Ignore:默认操作是忽略信号。
- Core:默认操作是终止进程并转储内核。
- Stop:默认操作是停止进程。
有关 Linux 信号的完整列表,包括每个信号的简短描述及发出信号时的默认行为,请通过调用下列命令查看 Section 7 中的信号手册:# man 7 signal。对于 Linux,请注意以下事项:
- SIGABRT 和 SIGIOT 是相同的。
- SIGCLD 和 SIGCHLD 是相同的。
- SIGPOLL 和 SIGIO 是相同的。
- 对于 Linux,SIGPWR 的默认操作是终止进程,而在 Solaris 中则忽略该操作。
表 2 显示了 Solaris 支持但 Linux on POWER 不支持的信号:
名称 | 默认操作 | 说明 |
---|---|---|
SIGEMT | core | 模拟陷阱 |
SIGWAITING | ignore | 线程库使用的并发信号 |
SIGLWP | ignore | 线程库使用的 Inter-LWP 信号 |
SIGFREEZE | ignore | 检查点暂停 |
SIGTHAW | ignore | 检查点继续 |
SIGCANCEL | ignore | 线程库使用的取消信号 |
SIGLOST | ignore | 资源丢失(运行于 Sparc 上的 Linux 支持该项) |
SIGXRES | ignore | 资源控制超出 |
在 Soalris 和 Linux 上,sigset_t 的定义有所不同。在 Linux 上,它在 /usr/include/bits/sigset.h 中定义为:
# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) typedef struct { unsigned long int __val[_SIGSET_NWORDS]; } __sigset_t; #endif |
在 Solaris 上,它在 /usr/include/sys/signal.h 中定义为:
清单 3. 如何在 Solaris 上定义 sigset_t
typedef struct { /* signal set type */ unsigned int __sigbits[4]; } sigset_t; |
系统中可以有两种不同的数据类型:基本数据类型 和衍生数据类型。
基本数据类型是 C 和 C++ 语言规范定义的所有数据类型。表 3 对 Linux on POWER 和 Solaris 中的基本数据类型进行了比较(值以字节为单位):
基本类型 | Linux on POWER, ILP32 | Linux on POWER, LP64 | Solaris, ILP32 | Solaris, LP64 |
---|---|---|---|---|
_Bool,bool | 1 | 1 | 1 | 1 |
char | 1 | 1 | 1 | 1 |
wchar_t | 2 | 4 | 4 | 4 |
short | 2 | 2 | 2 | 2 |
int | 4 | 4 | 4 | 4 |
float | 4 | 4 | 4 | 4 |
long | 4 | 8 | 4 | 8 |
pointer | 4 | 8 | 4 | 8 |
long long | 8 | 8 | 8 | 8 |
double | 8 | 8 | 8 | 8 |
long double | 16* | 16* | 16 | 16 |
*从 Red Hat Enterprise Linux 5 (RHEL5) 和 SUSE Linux Enterprise Server 10 (SLES10) 开始,在 Linux on POWER 中 long double 的默认大小是 128 位。在 RHEL5 或 SLES10 之前,如果 XL 编译器中使用了编译器选项 -qldbl128,那么其大小可以增加到 128 位。
当在平台之间或在 32 位和 64 位模式之间移植应用程序时,需要考虑不同环境中可用对齐设置之间的差别,以避免可能发生的性能下降和数据损坏。对于 IBM XL C/C++ 编译器,集合(C/C++ 结构/联合及 C++ 类)内的每个数据类型将根据 linuxppc 或 bit-packed 规则沿字节边界对齐(使用 -qalign 选项),其中 linuxppc 为默认值。linuxppc 使用 GNU C/C++ 对齐规则维护与 GNU C/C++ 对象的二进制兼容性。
表 4 用显示了 linuxppc 和 bit-packed 规则的对齐值:
数据类型 | linuxppc | bit-packed |
---|---|---|
_Bool,bool | 1 | 1 |
char | 1 | 1 |
wchar_t (32-bit) | 2 | 1 |
wchar_t (64-bit) | 4 | 1 |
int | 4 | 1 |
short | 2 | 1 |
long (32-bit) | 4 | 1 |
long (64-bit) | 8 | 1 |
long long | 8 | 1 |
float | 4 | 1 |
double | 8 | 1 |
long double | 16 | 1 |
SPARC 平台通常要求数据对齐遵循相等的数据大小:2 字节类型必须在 2 字节区域内,4 字节类型必须在 4 字节区域内。因此,当您从 Solaris 移植到 Linux 时,必须特别注意 Solaris 和 Linux 之间的不同大小的数据类型。
衍生数据类型是现有基本类型或其他衍生类型的衍生物或结构。根据使用的数据模型(32 位或 64 位)和硬件平台,系统衍生数据类型可以具有不同的字节大小。表 5 显示了 Linux 中的一些衍生数据类型,它们与 Solaris 中的那些衍生数据类型不同:
数据类型 | Solaris ILP32 | Solaris LP64 | Linux on POWER ILP32 | Linux on POWER LP64 |
---|---|---|---|---|
gid_t | long | int | unsigned int | unsigned int |
mode_t | unsigned long | unsigned int | unsigned int | unsigned int |
pid_t | long | int | int | int |
uid_t | long | int | unsigned int | unsigned int |
wint_t | long | int | unsigned int | unsigned int |