c - Pthreads 和不透明类型

标签 c struct pthreads unions

<分区>

我正在阅读 pthreads 库的头文件,并在 bits/pthreadtypes.h 中找到了互斥量(和其他类型)的这个特定定义:

typedef union
{
  struct __pthread_mutex_s
  {
    int __lock;
    unsigned int __count;
    int __owner;
    /* KIND must stay at this position in the structure to maintain
       binary compatibility.  */
    int __kind;
    unsigned int __nusers;
    __extension__ union
    {
      int __spins;
      __pthread_slist_t __list;
    };
  } __data;
  char __size[__SIZEOF_PTHREAD_MUTEX_T];
  long int __align;
} pthread_mutex_t;

它并不完全像这样,但为了清楚起见,我对其进行了简化。在 header 和实现文件中创建一个具有两个不同定义的结构,作为真正结构定义的实现,而 header 只是实际结构大小的字符缓冲区,用作隐藏实现的技术(不透明类型) 但在调用 malloc 或在堆栈中分配对象时仍会分配正确数量的内存。

这个特定的实现使用了一个 union 并且仍然公开了结构的定义和字符缓冲区,但似乎没有提供任何隐藏类型的好处,因为结构仍然公开并且二进制兼容性是仍然依赖于结构不变。

  1. 为什么 pthreads 中定义的类型遵循这种模式?
  2. 如果您不提供二进制兼容性(如不透明指针模式),那么使用不透明类型有什么好处?我知道安全是其中之一,因为您不允许用户篡改结构的字段,但还有其他问题吗?
  3. 公开的 pthread 类型主要是为了允许静态初始化还是有任何其他特定原因?
  4. 遵循不透明指针模式(即根本不公开任何类型并且不允许静态初始化)的 pthreads 实现是否可行?或者更具体地说,是否存在只能通过静态初始化解决问题的情况?
  5. 完全不相关,C 中是否有“主线程之前”?

最佳答案

我的看法是 __size__align 字段独立于 __data 指定(猜猜是什么 :-) )结构的大小和对齐方式> 结构。因此,数据可以更小,对齐要求也更少,可以在不破坏这些基本假设的情况下自由修改。反之亦然,这些基本特征可以在不改变数据结构的情况下改变,比如here。 .

重要的是要注意,如果 __data 的大小变得大于 __SIZEOF_PTHREAD_MUTEX_T 指定的大小,则 __pthread_mutex_init() 中的断言会失败:

assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T);

将此断言视为此方法的重要组成部分。

因此,结论是这样做不是为了隐藏实现细节,而是为了使数据结构更可预测和可管理。对于一个广泛使用的库来说,这一点非常重要,它应该非常关心向后兼容性和对该结构所做的更改对其他代码的性能影响。

关于c - Pthreads 和不透明类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24067207/

相关文章:

c - 单链表上最后一个不需要的节点

c++ - 使用 char* 构建动态结构的更好方法?

c - 我试图在 thread_func 调用中通过 for 循环的每次传递请求打印线程数

c - 通用快速排序由于某种原因不起作用

c - 以太网数据包中的 MAC 地址与 TCP/IP 数据包有何关联?

c - 删除C中的最后一行

c - C 编程中的映射文件

go - 当另一个对象告诉结构更新时结构字段不更新

c++ - 如何在Windows上为g++安装pthreads.h?

c++ - boost::thread_specific_ptr/cleanup 与 atexit 执行顺序