Объясните как работает мьютекс - PullRequest
1 голос
/ 15 июля 2010

Теперь я пытаюсь выучить многопоточность и мьютекст. Но я этого не понимаю. Например, я добавляю элементы в список в другой ветке, а затем в основной программе:

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

Что происходит в этом случае со списком? Список добавленных элементов, а также отсутствие доступа из основного потока до g_mutex_unlock? Или я неправильно это понимаю?

Спасибо.

Спасибо.

Ответы [ 5 ]

4 голосов
/ 15 июля 2010

Пока мьютекс заблокирован, любой другой поток, который хочет его заблокировать, будет блокироваться до тех пор, пока мьютекс не будет разблокирован потоком, который в данный момент удерживает блокировку. Это не относится к объекту списка - если какой-то другой поток не пытается заблокировать тот же мьютекс, он может попытаться сделать что-нибудь со списком, и может возникнуть параллельный доступ, что приведет к повреждению списка.

Так что блокировка мьютекста - это соглашение. Вызывающая сторона должна соблюдать соглашение - попытаться получить блокировку мьютекса перед доступом к защищенному объекту данных. Отображение между объектами данных и мьютексами зависит от разработчика.

3 голосов
/ 15 июля 2010

Нет, любой, кто получает доступ к списку за пределами , мьютекс все еще может видеть изменения. Но вы не должны этого делать (обычно, во всяком случае). Суть в том, чтобы изменения стали фактически атомарными - вы бы заблокировали мьютекс везде , необходимый для доступа к общему состоянию. Это эффективно сериализует доступ между потоками, поэтому каждый поток может вносить свои изменения (или читать свои данные), зная, что больше ничего не мешает списку. Тем не менее, это сотрудничество - если вы забудете заблокировать мьютекс при доступе к списку, вы рискуете столкнуться с гонкой данных.

2 голосов
/ 15 июля 2010

Мьютекс и список - это два отдельных объекта.Ничто не мешает вам получить доступ к списку за пределами мьютекса и, таким образом, не гарантирует взаимное исключение (отсюда и название мьютекса).

Вы часто будете видеть такой код:

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

Это гарантирует, что список всегда доступен безопасно.Если другой метод обращается к списку напрямую, не используя тот же мьютекс, нет гарантии, в каком состоянии находится список (например, какие данные извлекаются / добавляются).

1 голос
/ 15 июля 2010

Мьютекс означает: взаимоисключающий.Это означает, что объект мьютекса может быть доступен только одному пользователю одновременно.Есть разные подходы к обработке, один занят ожиданием, и есть семафоры.Некоторые процессоры имеют мьютекс-подобные инструкции, тестируют и устанавливают как атомарную операцию.

1 голос
/ 15 июля 2010

Эта ссылка должна дать вам понимание мьютекса и многопоточности. Разница между замками, мьютексом и критическими секциями

...