为什么`pthread_rwlock_t`的ABI在版本之间会有很大差异? [英] Why `pthread_rwlock_t`'s ABI differs a lot among versions?

查看:94
本文介绍了为什么`pthread_rwlock_t`的ABI在版本之间会有很大差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 pthread_rwlock_t 的不同版本的实现.

I am looking into different versions of implementation of pthread_rwlock_t.

  1. GLIBC2.30

  1. GLIBC2.30

typedef union
{
  struct __pthread_rwlock_arch_t __data;
  char __size[__SIZEOF_PTHREAD_RWLOCK_T];
  long int __align;
} pthread_rwlock_t;

struct __pthread_rwlock_arch_t
{
  unsigned int __readers;
  unsigned int __writers;
  unsigned int __wrphase_futex;
  unsigned int __writers_futex;
  unsigned int __pad3;
  unsigned int __pad4;
  ...

  • GLIBC2.17

  • GLIBC2.17

    typedef union
    {
    # ifdef __x86_64__
      struct
      {
        int __lock;
        unsigned int __nr_readers;
        unsigned int __readers_wakeup;
        unsigned int __writer_wakeup;
        unsigned int __nr_readers_queued;
        unsigned int __nr_writers_queued;
        int __writer;
        int __shared;
    ...
    
    } pthread_rwlock_t;
    

  • 它们的实现似乎有所不同,并给我带来了一些困难.因为我有一个链接到GLIBC2.30的程序 a 和一个链接到GLIBC2.17的程序 b .这两个程序将在shm上共享的同一 pthread_rwlock_t 上运行.我是通过静态链接GLIBC实现的.

    Their implementations seem different and cause some difficulties for me. Because I have a program a which is linked to GLIBC2.30 and a program b which is linked to GLIBC2.17. Both programs will operate on the same pthread_rwlock_t which is shared on the shm. I achieved this by staticly linking GLIBC.

    但是,由于GLIBC2.30和GLIBC2.17的定义不同,它们对shm上的 pthread_rwlock_t 对象的解释也有所不同.例如,如果GLIBC2.30将 __ readers 设置为2,然后由GLIBC2.17访问,则它会认为 pthread_rwlock_t 已锁定并因此而休眠.但是, pthread_rwlock_t 未锁定.

    However, GLIBC2.30 and GLIBC2.17 will interpret the pthread_rwlock_t object on the shm differently, because their definition differ. For example, if __readers is set to 2 by GLIBC2.30 then accessed by GLIBC2.17, it will think the pthread_rwlock_t is locked and sleep on that. However, the pthread_rwlock_t is not locked.

    我的问题是:

    1. 为什么 pthread_rwlock_t 在各个版本之间有很大变化?是因为它想支持更多功能还是提高性能?
    2. 是否可以使用GLIBC2.30和GLIBC2.17来操作同一rwlock?
    1. Why pthread_rwlock_t changes this much among versions? Is it because it want to support more features, or enhance performance?
    2. Is there any ways I can may GLIBC2.30 and GLIBC2.17 operate the same rwlock?

    更新

    我查看了更多源代码,并找到:

    I look more source codes, and find:

    1. GLIBC2.17使用 lll_lock 来实现
    2. GLIBC2.30使用原子操作哟工具

    然后我还有一个问题,不同版本的GLIBC是否不能相互压缩?所以我不能在不同版本的GLIBC之间使用shm吗?

    Then I have another question, are different versions of GLIBC not compactible with each other? So I can't use shm between different versions of GLIBC?

    推荐答案

    1. 为什么pthread_rwlock_t在版本之间有很大变化?是因为它想支持更多功能还是提高性能?

    因为glibc维护者认为更改它具有优势.

    Because the glibc maintainers decided that there was an advantage to be gained in changing it.

    与标准标头定义的大多数结构一样, struct pthread_rwlock_t 的布局未标准化.与某些此类结构一样,甚至没有任何成员名称是标准化的.我认为结构不是完全不透明的原因是可以直接声明实例,而不是要求它们由某种构造函数生成.

    As with most structures defined by the standard headers, the layout of struct pthread_rwlock_t is not standardized. As with some such structures, not even any of the member names are standardized. I presume that the reason the structure is not totally opaque is so that instances can be declared directly instead of requiring them to be produced by some kind of constructor function.

    如果您构建依赖于该结构的特定布局的程序,那么您将大步向前,除非您针对其构建的pthreads版本提供了任何东西.定义由编译时使用的 pthreads.h 版本提供,并且必须与相应的库匹配.

    You are going way out on a limb if you construct programs that depend on a specific layout of that structure, except whatever the version of pthreads you build against provides. That definition is provided by the version of pthreads.h used at compile time, and it must be matched with the corresponding library.

    1. 是否可以使用GLIBC2.30和GLIBC2.17来操作同一rwlock?

    我认为您已经知道答案是否".每个库实现都直接依赖于该结构的特定布局,并且布局根本不重合.如果要在进程之间共享pthreads rwlock,则除了在其上配置其 pshared 属性外,还应针对相同版本的libpthread及其标头(或任何提供pthreads的库)构建协作程序.执行).在实践中可以接受某些版本上的偏差,但是如果您要冒风险,则必须由您来测试和验证特定的组合.

    I think you already know that the answer is "no". Each library implementation has direct dependencies on a specific layout of that structure, and the layouts do not coincide at all. If you want to share a pthreads rwlock among processes then, in addition to configuring its pshared attribute on, you should build the cooperating programs against the same version of libpthread and its headers (or whatever library provides your pthreads implementation). Some version skew may be acceptable in practice, but if you want to risk that then it's on you to test and validate specific combinations.

    不同版本的GLIBC是否不能相互压缩?

    are different versions of GLIBC not compactible with each other?

    很明显,涉及您特定问题的两个版本与您希望的方式不兼容.Glibc关于 link 兼容性非常好:

    Clearly the two versions involved in your particular problem are not compatible in the way you hoped. Glibc is pretty good about link compatibility:

    • 与一个版本动态链接的程序很可能会与更高版本的共享库正确互操作;和

    • a program dynamically linked against one version will very likely interoperate correctly with the shared libraries of later versions; and

    一个可以针对一个版本正确构建和静态链接的程序几乎可以肯定会针对更高版本正确构建和静态链接,甚至可以使用从C语言标准中删除的功能(我正在寻找您), gets()).

    a program that builds and statically links correctly against one version will almost certainly build and statically link correctly against later versions, even to the point of use of functions removed from the C language standard (I'm looking at you, gets()).

    但是,对于库提供的大多数结构类型的内部表示形式,没有要求,也没有合理的期望.请注意,即使只是添加成员,以使类型的大小发生变化,也会产生不兼容的表示形式.

    But there is no requirement for, nor reasonable expectation of, consistent internal representations of most structure types provided by the library. Note well that even just adding members, so that a type's size changes, produces an incompatible representation.

    所以我不能在不同版本的GLIBC之间使用shm?

    So I can't use shm between different versions of GLIBC?

    使用基于C语言内置数据类型( int double etc .)以及具有标准化表示形式的代码( int32_t etc ).但是原则上,即使内置数据类型的表示形式也可能在版本之间发生变化.

    Sharing memory across programs built against different versions of Glibc can probably be done successfully with data types that are fully defined by you based on the C language's built-in data types (int, double, etc.) and those with standardized representations (int32_t, etc.). In principle, however, even the representations of built-in data types might change between versions.

    我想可能有为此目的而设计的C库(尽管我什么都不知道),但是总的来说,C实现几乎不能保证内存中数据表示的兼容性.通常,您不能依靠库的不同版本来提供大多数其他数据类型的可互操作的内存中表示形式.

    I suppose there might be C libraries designed for this express purpose (though I don't know any), but in general, C implementations make very few guarantees about compatibility of in-memory data representation. You cannot, in general, rely on different versions of the library to provide interoperable in-memory representations of most other data types.

    这篇关于为什么`pthread_rwlock_t`的ABI在版本之间会有很大差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆