我从一个由互斥锁控制的固定大小的全局池中分配我的pthread特定于线程的数据。 (有问题的代码不允许动态分配内存;允许使用的所有内存都由调用者作为单个缓冲区提供.pthreads可能会分配内存,我不能说,但这并不意味着我的代码被允许。)
这在创建数据时很容易处理,因为该函数可以检查pthread_getspecific
的结果:如果它返回NULL
,则可以在那里获取全局池的互斥锁,然后是池条目获取,并使用pthread_setspecific
设置值。
当线程被销毁时,析构函数(根据pthread_key_create
)被调用,但是pthreads手册对于可能存在的任何限制有点模糊。
(我不能对线程代码强加任何要求,例如需要它在退出之前手动调用析构函数。所以,我可以保留分配的数据,并且可能将池视为某种缓存,重用LRU基础上的条目一旦变满 - 这可能是我在使用本机API时在Windows上采用的方法 - 但最好的方法是在每个线程被销毁时正确释放每线程数据。 )
我可以在析构函数中使用互斥锁吗?如果某个其他线程在该点采用了互斥锁,那么线程破坏会延迟一点没有问题。但是这可以保证有效吗?我担心的是该线程可能“不再存在”。我使用引号,因为当然它仍然存在,如果它仍在运行代码! - 但它是否足够存在以允许获取互斥量?这是在任何地方记录的吗?
答案 0 :(得分:1)
pthread_key_create()
rationale似乎有理由从析构函数中做任何你想做的事,只要你让信号处理程序不要调用pthread_exit()
:
没有析构函数安全函数的概念。如果应用程序没有从信号处理程序调用pthread_exit(),或者它在调用async-unsafe函数时阻止其处理程序可能调用pthread_exit()的任何信号,则可以从析构函数安全地调用所有函数。
但请注意,本节内容丰富,而非规范性。
线程的存在或不存在很可能不会影响互斥锁,除非互斥锁是错误检查。即使这样,内核仍在调度你的析构函数运行的任何线程,所以应该有足够的线程来解决。