我正在阅读unix环境中的Advance Programming一书中的Thread Synchronization
。
In this section,有一个示例将mutex与动态分配的对象一起使用。我对此有些怀疑。
在这里,我正在分享事件(自上而下)的时间表,以解释我的疑惑:
ds
。 Thread1需要使用ds
进行大量的工作,即Thread1将长时间获取此锁。 mutex_t
变量获取锁。 mutex_t
变量的锁定,所以当Thread2在递增计数之前调用lock()
时,它必须等到Thread1解锁。质疑:
foo_rele()
再次锁定并减少计数。现在有可能在Thread2递增计数之前,Thread1递减它。如果是(根据我)那么我的数据结构将被销毁?所以我认为这本书的例子有一点点错误。如果我们使用不同的mutex_var来增加计数会更好吗? 答案 0 :(得分:2)
一个。我认为在术语“全局列表”下,作者理解线程之间共享的所有变量。
示例:
struct foo* shared_foo; /* This pointer is shared between all threads */
struct foo* foo_alloc(void)
{
/* This pointer is local to the thread which allocates the memory */
struct foo *fp;
if ((fp = malloc(sizeof(struct foo))) != NULL) {
/* whatever */
}
/* local pointer value returned */
return(fp);
}
/* probably somewhere in the code the shared pointer (on the 'global list') is initialized this way */
shared_foo = foo_alloc();
B中。嗯......我真的不明白你说的话。你能把你的情节写成清单吗?在我看来,f_count
在初始化期间设置为标记'此互斥锁正在使用'。因此,当互斥锁空闲时,f_count
值设置为1.当Thread1
获取锁定时,它的值设置为2.当它释放锁定时,该值将设置回1.有效{ {1}}值为:1(初始化和免费)和2(初始化和忙碌)。要释放互斥锁,您只需在f_count
= 2)时调用两次foo_rele
,或者在空闲时调用一次f_count
= 1)。然后f_count
值达到0并删除互斥锁。
答案 1 :(得分:2)
是的,所以示例11.10是关于结构foo中的内容的全部内容。每个结构都有一个锁,因此对于线程1来操作对象,线程1需要将互斥锁保存在对象中。
给出的例子不完整,我可以理解你的困惑。在线程不再需要该对象之前,不应该调用foo_rele。如果另一个线程想要使用foo,则应该调用foo_hold()来增加引用计数(fp-> count ++)。是的,有一个竞争条件,线程2可能想要得到它,而线程1正在释放它。
这对多线程编程来说绝对不常见 - 一个线程可能会删除你想要在你的线程中工作的东西,除非代码是专门编写的以避免这种情况。避免例如包括对象列表的锁定,并且如果我的线程持有列表锁定,则其他线程不能从列表中添加或删除事物(并且不应该搜索列表,因为我可能只是添加或删除某些内容,并且无法保证列表是一致的)。
我希望这会有所帮助。
答案 2 :(得分:2)
线程共享内存,因此任何全局变量对同一进程中的所有线程都是可见的(因此不需要将指针传递给每个线程)。
使用互斥锁时,必须指望线程可以按任何顺序锁定互斥锁(POSIX不保证任何特定顺序)。因此,完全可能的是,线程1在任何其他线程获取对互斥锁的访问权之前创建,使用和销毁该结构。
P.S。我理解你的疑虑。我在代码片段中真正缺少的是其他互斥锁实际上阻止了同时写入结构。