C++ pthread_key_t和pthread_once_t?

C++ pthread_key_t和pthread_once_t?,c++,pthreads,unix,C++,Pthreads,Unix,从pthreads开始,我无法理解pthread_key_t和pthread_once_t的业务是什么 如果可能的话,有人能用简单的语言举例说明吗 感谢pthread\u key\u t用于创建线程:每个线程都有自己的数据变量副本,而不是所有线程共享一个全局(或函数静态、类静态)变量。TLS由一个键索引。有关更多详细信息,请参见等人 pthread\u once\u t是一个控件,用于仅使用执行函数一次。假设您必须调用一个初始化例程,但必须只调用该例程一次。此外,您必须在启动多个线程之后调用它。

从pthreads开始,我无法理解pthread_key_t和pthread_once_t的业务是什么

如果可能的话,有人能用简单的语言举例说明吗


感谢

pthread\u key\u t
用于创建线程:每个线程都有自己的数据变量副本,而不是所有线程共享一个全局(或函数静态、类静态)变量。TLS由一个键索引。有关更多详细信息,请参见等人


pthread\u once\u t
是一个控件,用于仅使用执行函数一次。假设您必须调用一个初始化例程,但必须只调用该例程一次。此外,您必须在启动多个线程之后调用它。一种方法是使用
pthread_once()
,它保证无论有多少线程试图一次调用例程,只要每次调用中使用相同的控制变量,例程都只被调用一次。使用
pthread_once()
通常比使用其他替代方法更容易。

不,不能用外行术语解释。在C++中,外行无法成功地使用P螺纹编程。需要一位被称为“计算机程序员”的专家:

pthread\u once\u t
是一小段存储空间,必须对其进行
pthread\u once
访问,以确保其按照tin上的说明执行。每个once控件都将允许一个init例程被调用一次,并且只调用一次,而不管它从多少线程被调用多少次,可能是并发的。通常,对于计划按需以线程安全的方式初始化的每个对象,都使用不同的once控件。您可以将其视为一个整数,该整数作为是否选择线程进行初始化的标志进行原子访问。但是由于
pthread\u once
是阻塞的,我想如果实现也能塞进一个同步原语(这是我唯一一次实现
pthread\u once
,我不能,所以once控件采用了3种状态中的任何一种(开始、初始化、完成).但我无法更改内核。异常情况)


pthread\u key\t
类似于访问线程本地存储的索引。您可以认为每个线程都有一个从键到值的映射。向TLS添加新条目时,
pthread\u key\u create
为其选择一个键,并将该键写入指定的位置。然后,只要您想要为当前线程设置或检索该TLS项的值,就可以从任何线程使用该键。TLS为您提供密钥而不是让您选择密钥的原因是,不相关的库可以使用TLS,而无需合作以避免使用相同的值和破坏彼此的TLS数据。例如,pthread库可能保留一个全局计数器,并在第一次调用
pthread\u key\u create
时分配键0,第二次调用时分配键1,依此类推。

哇,这里的其他答案太冗长了

pthread\u once\u t
存储
pthread\u once()
的状态。调用
pthread\u一次(&s,fn)
调用
fn
并设置
s
指向的值,以记录它已执行的事实。对
pthread\u once()
的所有后续调用都是noop。这个名字现在应该很明显了


pthread\u once\t
应该初始化为
pthread\u once\u INIT

并没有用“外行”的术语解释,Adam的答案很简短,切中要害。对于新手,我建议阅读《Linux编程接口书》的第31章:线程:线程安全和每线程存储,你们会在那个里得到所有答案。在了解
threadfunctionkeythread特定数据
模型之前,您无法理解这些变量背后的基本原理。