gpt4 book ai didi

c - GCC 警告 gettid() 系统调用包装器,glibc 2.30-8

转载 作者:行者123 更新时间:2023-12-03 09:53:43 48 4
gpt4 key购买 nike

man pageSO post#1/SO post#2都提示gettid()在 glibc 2.30 中实现。我想我正在使用 GLIBC 2.30-8,根据 ldd --version ,但是 gcc仍然提示 - 警告:隐式声明函数“gettid”;您指的是 'getgid' 吗? [-Wimplicit-function-declaration]。我可以忽略警告,程序运行良好。

我试图与 gettid() 一起使用的标题是 <sys/types.h> ,按照手册页。我错过了什么?

调用 syscall(SYS_gettid)带标题<sys/syscall.h>不触发来自 gcc 的警告.

最佳答案

注意:这是非常新的,不应该在没有某些条件的情况下依赖它。而且,可能永远都无法依靠。

见下文。

直到 2019 年 2 月,这是联机帮助页上的内容:

来自:man gettid :

Note: There is no glibc wrapper for this system call; see NOTES.



而且,从注释:

Glibc does not provide a wrapper for this system call; call it using syscall(2).



有关更多详细信息,请参阅 NOTES 部分的其余部分。这是因为他们希望你使用其他东西,即 pthread_self兼容的。

这是一个 glibc我个人不同意的怪癖/哲学。

因为,有时需要使用real/linux tid值(value)。

新方法是 [截至 2019 年 2 月,根据 Joseph]:
#define _GNU_SOURCE
#include <unistd.h>

获得 gettid宣言。

但是...

这永远不能被依赖 [没有 #if/#ifdef ] 因为 gettid系统调用从 2004 年左右的 linux 2.4 开始就出现了。

因此,它采取了 glibc 15年添加一个包装函数!?!? :-( IMO,太少,太晚了。

使用新方法时,它会破坏与 15 年内发布的所有发行版的向后兼容性。

所以,忽略这一点并继续使用 syscall是要走的路。这是保持向前/向后兼容性的最简单方法。

我们可以创建包装器,但它更复杂 [类似于]:
#if __GLIBC_PREREQ(2,30)
#define _GNU_SOURCE
#include <unistd.h>

#else

#include <sys/syscall.h>

pid_t
gettid(void)
{

return syscall(SYS_gettid);
}
#endif

事实上,它甚至比这更复杂,因为我们必须确保我们有 __GLIBC_PREREQ 的定义。 [和 __GLIBC____GLIBC_MINOR__ ] 在我们开始包括东西之前。

而且,做到这一点是有问题的。因此,人们可能会被迫总是这样做:
#define _GNU_SOURCE
#include <unistd.h>

然后添加 #if然后。或者,无论实际的神秘方式是什么[我无法亲自测试,因为我在使用旧方法的系统上]。

它很乱,[IMO] 不值得麻烦。

而且,情况更糟。

由于旧方法已经存在了这么久,许多应用程序已经定义了自己的 gettid包装函数。因此,新声明可能会与此冲突。

因此,无需做任何事情,开发人员就可以重新编译他们 [以前] 的工作代码,并且构建现在会出错。

为了防止这种情况, unistd.h应该只声明 gettid如果用户放了一些 #define在包含它之前(类似于 _GNU_SOURCE ),例如:
#define _DECLARE_GETTID
#include <unistd.h>

而且,由于新方法打破了 15 年的兼容性,联机帮助页需要记录这一事实并解释旧方法。

因为,开发人员试图编写跨平台代码、跨多个内核版本和多个 glibc版本,需要了解这一点。

更新:

There's very good reason it was not added before - it was not a supported abstraction for application use.



这仍然没有给他们打破向后兼容性的许可。

并且,必须为特殊应用程序(例如那些与给定设备驱动程序密切配合的应用程序)合成缺失的功能

For a long time



15+ 年...

glibc was entertaining the idea of possible thread models where the kernel tid would not be an invariant for the thread lifetime.



内核对 pthread_t 一无所知.它只知道 tid .这就是应用程序必须与内核通信的方式(例如 tgkill )。

内核模型中没有任何内容可以改变 tid中游,它不会改变 pid在执行过程中的进程上。

那是因为内核处理 tid就像 pid出于调度的目的。有一个任务结构 [索引/标识为 pid/tid ] 每个进程和每个线程。

否则,将需要对所有内核调度程序、任务/线程层次结构等进行大修。因此, glibc一个人不可能做到这一点。而且,到底是为了什么?

clone syscall 来创建一个线程[可以选择使用相同的地址空间],这在很大程度上是一个不可见的区别,并且一个线程在被调度时获得相同的权重[基于调度程序和任务优先级]。

这是内核方法的一大好处:任务/线程在被调度时是一等公民[与 WinX 不同]。

旁注:我必须对实时嵌入式 H/W H.264 视频编码器进行编程,并且必须处理 nptl 的前身。 [即 linuxthreads (?)] 并且它导致了吞吐量和延迟方面的严重问题。幸运的是, nptl在我们必须发货之前就出现了。区别是白天和黑夜。

It was only after relatively recent discussions that it was deemed ok.



内核 [和/或 POSIX] 定义语义,而不是 glibc . glibc 可以遵循和实现,而不是规定。

而且,因为 glibc人们顽固[和令人讨厌],花了15年的时间来决定[显而易见的],IMO,他们在这件事上失去了任何讨价还价的权利。

关于c - GCC 警告 gettid() 系统调用包装器,glibc 2.30-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61979901/

48 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com