为什么 glibc/musl 中的 sigset_t 在 64 位 Linux 上有 128 字节大?

PSk*_*cik 1 linux c signals glibc

为什么sigset_t在 64 位 Linux 上,glibc 和 musl 有 128 字节大?

#include <signal.h>
#include <stdio.h>
int main()
{
    printf("%zu\n", sizeof(sigset_t)); //prints 128 with both glibc and musl
}
Run Code Online (Sandbox Code Playgroud)

64 / 8 = 8 ( number_of_signals / CHAR_BIT) 不够吗?

Ste*_*itt 7

我不知道最初的原因;早在 1996 年,Linux 特定的标头就添加了以下定义:

/* A `sigset_t' has a bit for each signal.  Having 32 * 4 * 8 bits gives                                           
   us up to 1024 signals.  */                                                                                      
#define _SIGSET_NWORDS 32                                                                                          
typedef struct                                                                                                     
{                                                                                                                  
  unsigned int __val[_SIGSET_NWORDS];                                                                              
} __sigset_t;
Run Code Online (Sandbox Code Playgroud)

并且这个“1024 信号”限制已保留在当前定义中:

/* A `sigset_t' has a bit for each signal.  */                                                                     

#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))                                                   
typedef struct                                                                                                     
  {                                                                                                                
    unsigned long int __val[_SIGSET_NWORDS];                                                                       
  } __sigset_t;
Run Code Online (Sandbox Code Playgroud)

这使得基于 1024 的计算更清晰(并在 64 位 x86 上产生 16 个无符号长整型,128 字节)。

据推测,glibc 维护者想要留下增长空间......

musl 旨在实现与 glibc for 的 ABI 兼容性sigaction,因此它使用相同的 1024 位(128 字节)大小

TYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
Run Code Online (Sandbox Code Playgroud)