用于在C中动态分配内存的互斥锁

时间:2012-12-29 11:37:34

标签: c multithreading pthreads mutex dynamic-allocation

我正在阅读unix环境中的Advance Programming一书中的Thread Synchronization

In this section,有一个示例将mutex与动态分配的对象一起使用。我对此有些怀疑。

在这里,我正在分享事件(自上而下)的时间表,以解释我的疑惑:

  1. 创建了Thread1。
  2. Thread1创建一个mutex var初始化它并将其放在一个全局列表中,以便其他人可以使用它。
  3. 现在,Thread1获得了一个锁,以使用共享数据结构说ds。 Thread1需要使用ds进行大量的工作,即Thread1将长时间获取此锁。
  4. 现在,当Thread1仍然获得锁定时,会创建Thread2。
  5. 现在Thread2也想使用ds。
  6. 因此,Thread2必须首先递增计数器,显示对ds的引用增加。为此,(根据书中)首先需要在递增计数之前使用相同的mutex_t变量获取锁。
  7. 但是由于Thread1已经获得了对此mutex_t变量的锁定,所以当Thread2在递增计数之前调用lock()时,它必须等到Thread1解锁。
  8. 质疑

    1. 关于他正在讨论哪个全局列表(意味着只是制作任何列表并将其引用到所有线程或任何特定列表)
    2. 当Thread1创建锁定变量时,它将计数设置为1.然后,Thread2正在等待将此计数增加到2.但是假设在执行当前工作后,Thread1不需要使用ds。因此,在解锁之前,它还会减少计数或首先将其解锁,然后调用foo_rele()再次锁定并减少计数。现在有可能在Thread2递增计数之前,Thread1递减它。如果是(根据我)那么我的数据结构将被销毁?所以我认为这本书的例子有一点点错误。如果我们使用不同的mutex_var来增加计数会更好吗?

3 个答案:

答案 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)

  1. 线程共享内存,因此任何全局变量对同一进程中的所有线程都是可见的(因此不需要将指针传递给每个线程)。

  2. 使用互斥锁时,必须指望线程可以按任何顺序锁定互斥锁(POSIX不保证任何特定顺序)。因此,完全可能的是,线程1在任何其他线程获取对互斥锁的访问权之前创建,使用和销毁该结构。

  3. P.S。我理解你的疑虑。我在代码片段中真正缺少的是其他互斥锁实际上阻止了同时写入结构。