为什么 sem_t 指针必须从偏移量 4 的倍数开始?

Why sem_t pointer have to start at multiple of 4 offset?

当您访问内存块时(f.e。在实际情况下使用 mmap)sem_t 的正确指针必须是 4 的倍数。如果不是,则 sem_init () 仍然没有 return -1(错误值),但 sem_t 无效。为什么会这样?

下面的代码显示了信号量的行为。

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <strings.h> //bzero

int main(int argc, const char *argv[]) {
  //sizeof(sem_t) == 32 on 86_64, 16 on 86
  void *adrr = malloc(sizeof(sem_t)*2);
  bzero(adrr, sizeof(sem_t)*2); 

  sem_t *sem1 = adrr+1;
  if(sem_init(sem1, 1, 0) == -1) printf("ERROR\n");
  sem_wait(sem1);
  printf("Not working\n");
  bzero(adrr, sizeof(sem_t)*2);

  sem_t *sem2 = adrr+2;
  sem_init(sem2, 1, 0);
  sem_wait(sem2);
  printf("Not working\n");
  bzero(adrr, sizeof(sem_t)*2); 

  sem_t *sem3 = adrr+3;
  sem_init(sem3, 1, 0);
  sem_wait(sem3);
  printf("Not working\n");
  bzero(adrr, sizeof(sem_t)*2);

  sem_t *sem4 = adrr+4;
  sem_init(sem4, 1, 0);
  sem_wait(sem4);
  printf("Working\n");
  free(adrr);
  return 0; 
}

ALL1 C 中的类型可能有对齐要求。这些要求始终是实现定义的,并且在不同的体系结构上甚至在同一体系结构上的不同编译器上可能不同(尽管这种情况很少见)。

违反实现定义的对齐要求会导致未定义的行为——任何事情都可能发生,但通常发生的情况是程序在访问未对齐的对象时出错或崩溃。

您似乎已经确定,在您的特定实现中,sem_t 的对齐要求为 4——在 32 位体系结构中相当常见。其他实现可能不同。


1你可以争辩说 char 从来没有对齐要求,或者它的对齐要求必须是 1