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

时间:2017-05-21 17:56:02

标签: c linux posix

当你访问内存块时(在实际情况下使用mmap),sem_t的正确指针必须是4的倍数。如果不是,那么sem_init()仍然不会返回-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; 
}

1 个答案:

答案 0 :(得分:2)

C中的

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

违反实现定义的对齐要求会导致未定义的行为 - 任何事情都可能发生,但一般情况下,当访问未对齐的对象时,程序会收到错误或崩溃。

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

1 你可以说char永远不会有对齐要求,或者它的对齐要求必须是1