解释它是如何工作的互斥量

时间:2010-07-15 05:59:03

标签: c multithreading mutex gtk

现在我尝试学习多线程和mutext。但我不明白。例如,我在anotyher线程中添加要列出的项目,然后是主程序:

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

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

谢谢。

谢谢。

5 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

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

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;
}

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

答案 3 :(得分:1)

这个链接必须让您了解互斥和多线程。 Difference between Locks, Mutex and Critical Sections

答案 4 :(得分:1)

Mutex意味着:相互排斥。这意味着,互斥对象只能由一个用户同时访问。有不同的approches如何处理,一个忙着等待,并有信号量。有些CPU有像指令一样的互斥,测试和设置为原子操作。