从pthreads开始,我无法理解pthread_key_t和pthread_once_t的业务是什么?
如果有可能,有人会用简单的例子解释一下吗?
感谢
答案 0 :(得分:13)
pthread_key_t
用于创建线程thread-local storage:每个线程都获得自己的数据变量副本,而不是共享全局(或函数静态,类 - 静态)变量的所有线程。 TLS由密钥索引。有关详细信息,请参阅pthread_getspecific
等。
pthread_once_t
是仅使用pthread_once
执行一次函数的控件。假设您必须调用初始化例程,但您必须只调用该例程一次。此外,您必须调用它的点是在您已启动多个线程之后。执行此操作的一种方法是使用pthread_once()
,这可以保证只要一次调用多少线程,您的例程将只被调用一次,只要您在每次调用中使用相同的控制变量即可。使用pthread_once()
通常比使用其他替代方案更容易。
答案 1 :(得分:11)
不,不能用外行术语来解释。在C ++中,Laymen无法使用pthread成功编程。它需要一位称为“计算机程序员”的专家: - )
pthread_once_t
是pthread_once
必须访问的一点存储空间,以确保它能够执行它在锡上所说的内容。每次一次控制都将允许一个init例程被调用一次,而且只调用一次,无论从多少个线程调用多少次,可能同时调用。通常,您为计划按照线程安全的方式按需初始化的每个对象使用不同的一次控件。您可以将它视为一个整数,它可以原子方式作为标志访问,无论是否已选择一个线程来执行init。但是因为pthread_once
是阻塞的,我想如果实现也可以填充同步原语(我唯一一次实现pthread_once
,那我就可以了。所以曾经的控制采取了3种状态中的任何一种(开始,初始化,完成)。但后来我无法改变内核。不寻常的情况)。
pthread_key_t
就像是访问线程本地存储的索引。您可以将每个线程视为具有从键到值的映射。向TLS添加新条目时,pthread_key_create
会为其选择一个密钥,并将该密钥写入您指定的位置。然后,只要您想为当前线程设置或检索该TLS项的值,就可以从任何线程使用该键。 TLS为您提供密钥而不是让您选择密钥的原因是,不相关的库可以使用TLS,而无需合作以避免使用相同的值并且摧毁彼此的TLS数据。 pthread库可能例如保留一个全局计数器,并且第一次调用键0 pthread_key_create
被调用,第二次调用1,依此类推。
答案 2 :(得分:2)
pthread_once_t
存储pthread_once()
的状态。调用pthread_once(&s, fn)
调用fn
并设置s
指向的值以记录它已被执行的事实。对pthread_once()
的所有后续调用都是noops。这个名字现在应该变得明显了。
pthread_once_t
应初始化为PTHREAD_ONCE_INIT
。