【问题标题】:Explain how it works mutex解释它是如何工作的互斥锁
【发布时间】:2010-07-15 05:59:02
【问题描述】:

现在我正在尝试学习多线程和 mutext。但我不明白。例如,我将项目添加到另一个线程中的列表然后是主程序:

GMutext* lock;
g_mutex_lock (lock);
g_list_prepend(list, "Some data");
g_mutex_unlock (lock);

在这种情况下,列表会发生什么?添加元素的列表,以及在 g_mutex_unlock 之前无法从主线程访问?还是我理解错了?

谢谢。

谢谢。

【问题讨论】:

    标签: c multithreading mutex gtk


    【解决方案1】:

    当互斥锁被锁定时,任何其他想要锁定它的线程都会阻塞,直到互斥锁被当前持有锁的线程解锁。这与列表对象无关 - 如果其他线程不尝试锁定同一个互斥锁,则可以尝试对列表执行任何操作,并且可能会发生并发访问导致列​​表损坏。

    所以锁定 mutext 是一种惯例。调用者必须遵守约定——在访问受保护的数据对象之前尝试获取互斥锁。数据对象和互斥体之间的映射取决于开发人员。

    【讨论】:

    • 感谢您的回复。所以我理解正确。目前没有人可以访问该列表?
    • 只有那些试图获得锁的人才没有并发访问权限。
    • @sterh:遵循在触摸列表之前获取互斥体的协议的人无法访问该列表。如果您忘记先获取互斥锁,则没有什么可以阻止您在另一个线程“拥有”它时操作列表,因为他们真正拥有的只是互斥锁。
    【解决方案2】:

    不,任何访问列表在互斥锁之外的人仍然可以看到更改。但是你不应该这样做(通常,无论如何)。关键是让更改有效地变成原子的 - 您将锁定访问共享状态所需的互斥锁everywhere。这有效地序列化了跨线程的访问,因此每个线程都可以进行更改(或读取其数据),而知道没有其他东西会弄乱列表。虽然这是合作的 - 如果您在访问列表时忘记锁定互斥锁,您将面临数据竞争的风险。

    【讨论】:

      【解决方案3】:

      互斥锁和列表是两个独立的对象。没有什么可以阻止您访问互斥锁之外的列表,因此不能保证互斥(因此称为互斥锁)。

      你会经常看到这样的代码:

      GMutext* lock;
      GList* list
      
      void addData(string data) {
        g_mutex_lock (lock);
        g_list_prepend(list, data);
        g_mutex_unlock (lock);
      }
      
      string getData() {
        g_mutex_lock (lock);
        GList* data = g_list_first (list);
        g_list_remove(list, data);
        g_mutex_unlock (lock);
        return data;
      }
      

      这可确保始终安全地访问列表。如果另一种方法直接访问列表而不使用相同的互斥锁,则无法保证列表可能处于什么状态(例如检索/添加什么数据)。

      【讨论】:

        【解决方案4】:

        互斥的意思是:互斥。这意味着,互斥对象只能由一个用户同时访问。有不同的处理方法,一种是忙等待,一种是信号量。一些 CPU 具有类似指令、测试和设置为原子操作的互斥锁。

        【讨论】:

          猜你喜欢
          • 2018-03-27
          • 2012-07-31
          • 1970-01-01
          • 2018-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多