关于pthread_attr_t定义的困惑

时间:2019-04-14 14:35:37

标签: c unix pthreads

当我在VS代码中单击转到定义时,它会引导我:
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
定义是:

union pthread_attr_t
{
  char __size[__SIZEOF_PTHREAD_ATTR_T];
  long int __align;
};
#ifndef __have_pthread_attr_t
typedef union pthread_attr_t pthread_attr_t;
# define __have_pthread_attr_t 1
#endif

这个联合定义是什么? char数组还是long整数?如何将其用于存储pthread attrs?绝对是胡说八道。


然后我在 glibc-master 实现中搜索 pthread_attr_t ,发现3个最相关的事件: glibc-master/sysdeps/htl/bits/pthreadtypes.h

#include <bits/types/struct___pthread_attr.h>
typedef struct __pthread_attr pthread_attr_t;

glibc-master/sysdeps/htl/bits/types/struct___pthread_attr.h

很显然,这应该是正确的:

struct __pthread_attr
{
  struct sched_param __schedparam;
  void *__stackaddr;
  size_t __stacksize;
  size_t __guardsize;
  enum __pthread_detachstate __detachstate;
  enum __pthread_inheritsched __inheritsched;
  enum __pthread_contentionscope __contentionscope;
  int __schedpolicy;
};

glibc-master/sysdeps/nptl/bits/pthreadtypes.h

union pthread_attr_t
{
  char __size[__SIZEOF_PTHREAD_ATTR_T];
  long int __align;
};
#ifndef __have_pthread_attr_t
typedef union pthread_attr_t pthread_attr_t;
# define __have_pthread_attr_t 1
#endif

有人可以告诉我这是怎么回事吗?不知道该union的定义。 一个char数组还是一个long整数?如何将其用于存储pthread attrs?

忘了说了,我在CLion中调试,我看到的是union pthread_attr_t结构。

1 个答案:

答案 0 :(得分:2)

我认为这个想法是将那些类型公开为足够对齐的足够大小的不透明缓冲区。 ( 一种更现代的方法是使用_Alignas代替union

struct {
  _Alignas(long int)
  char __size[__SIZEOF_PTHREAD_ATTR_T];
};

) 这样一来,就可以将这些类型声明为堆栈式(auto存储期限)或静态(static / extern)以满足POSIX API的要求,而无需公开布局。

从技术上讲,这样的技巧是未定义的行为(违反严格的别名),但是使用单独的编译,编译器不应将其弄乱。

只要有足够的协议可以不直接访问pthread_attr_t类型的成员(如果有的话),就不需要做任何这样的事情,但是我想glibc正在尝试什么要做的是更强烈地弃用这种访问权限,以免抱怨用户最初不应该使用的私有API中的语义“损坏”。