Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Может ли другой поток изменить заблокированный мьютексом объект? / 7 сообщений из 7, страница 1 из 1
14.11.2015, 12:31
    #39103389
log_here
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
Иными словами, что блокируют мьютексы и критические секции: участки кода или объекты, находящиеся под их воздействием?
Верно ли, что заблокированный мьютексом член класса можно изменить другим потоком в другой функции этого же класса?
...
Рейтинг: 0 / 0
14.11.2015, 13:06
    #39103407
alexy_black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
мутекс блокирует только мутекс... больше ничего.
то есть..

Код: plaintext
1.
2.
3.
4.
5.
6.
void foo::some(){
  std::lock_guard<std::mutex> lock(mutex_);
  // some work
  bar_.change("some change");
  std::cout << "hello" << std::endl;
}



теперь эту функцию можно исполнять из любого потока. но, если другой поток испольнит такую функцию

Код: plaintext
1.
2.
3.
4.
void foo::other() {
  bar_.change("some other change");
  std::cout << "goodbay" << std::endl;
}



то он нарушит работу.. то есть вывестесь на экран может тогда

hegoodllobay
...
Рейтинг: 0 / 0
14.11.2015, 14:19
    #39103442
log_here
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
А если дописать
Код: plaintext
1.
2.
3.
4.
5.
void foo::other() {
  std::lock_guard<std::mutex> lock(mutex_);
  bar_.change("some other change");
  std::cout << "goodbay" << std::endl;
}



, то уже нельзя будет одновременно заходить в
Код: plaintext
1.
foo::some 

и
Код: plaintext
1.
foo::other

, в предположении, что мьютекс является членом foo?
Код: plaintext
1.
2.
3.
4.
class foo {
   std::mutex mutex_;
   // ...
}
...
Рейтинг: 0 / 0
14.11.2015, 14:22
    #39103443
wst
wst
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
Мутекс, хоть блокированный хоть что, сам по себе не защищает ничего. Это просто некое состояние, используя которое можно синхронизировать потоки с помощью прилагаемых методов и только их . А можно сделать memset(&mutex, 0, sizeof(mutex)) и никто и слова поперек не скажет (и не сможет предсказать в общем случае что из этого выйдет).
P.S. операции ввода-вывода атомарны друг относительно друга.
...
Рейтинг: 0 / 0
14.11.2015, 14:36
    #39103448
alexy_black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
log_here, да. то есть нужно определить какие имеено переменные защищает мутест. перед обращением к этим переменным, от куда угодно, обязательно нужно взять мутекс. если не возьмешь, защиты нет. то есть если один метод берет, а другой нет, то тот метод, который берет, можно вызывать из разных потоков, а тот который не берет, нельзя.

wst, ну да ,наверное с выводом я перепутал. но запись в поток не атомарна. то есть в запись
Код: plaintext
1.
std::cout << "hello " << "world" << std::endl;

может вклиниться любой другой код и получится hello other code world или что-нибудь в этом духе. то есть можно вклиниться между операторами <<
...
Рейтинг: 0 / 0
14.11.2015, 15:59
    #39103498
mcureenab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
log_hereА если дописать
Код: plaintext
1.
2.
3.
4.
5.
void foo::other() {
  std::lock_guard<std::mutex> lock(mutex_);
  bar_.change("some other change");
  std::cout << "goodbay" << std::endl;
}



, то уже нельзя будет одновременно заходить в
Код: plaintext
1.
foo::some 

и
Код: plaintext
1.
foo::other

, в предположении, что мьютекс является членом foo?
Код: plaintext
1.
2.
3.
4.
5.
class foo {
   std::mutex mutex_;
   // ...
  int share_;
}


Заходить можно, но только до точки std::lock_guard<std::mutex> lock(mutex_);
Т.е. метод some или other получает управление, выполняет код который предшествует созданию объекта lock, и блокируется на вызове lock, если mutex_ уже занят.
Нет никакой необходимости размещать создание блокировки в самом начале метода. И нет нужды удерживать блокировку до самого конца. В методе можно сгруппировать код, который пишет/читает разделяемую память и защитить только этот блок кода.

....
{
std::lock_guard<std::mutex> lock(mutex_);
l = share_;
share_ = l + 1;
}
...
...
Рейтинг: 0 / 0
14.11.2015, 16:27
    #39103515
alexy_black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Может ли другой поток изменить заблокированный мьютексом объект?
ну.. как бы мутокс блокируется вызовом метода mutex_.lock() и разблокируется вызовмо методв mutex_.unlock(); если один поток вызвал метод mutex_.lock(), то другой поток, который тоже вызовет lock на этом же метексе встанет и будет ждать, пока первый поток не вызовет mutex_.unlock(). на этом вся синхронизация.

std::lock_guard - это просто класс ,который в конструкторе вызовет lock для переданного мутекса, а в деструкторе unlock . поэтому когда из облатси видимости выйдет объект этого класса, мутекс разблокируется.

если его не использовать, то можно получить вечную блокировку.

Код: plaintext
1.
2.
3.
 mutex_.lock();
do_some();
mutex_.unlock();

если вызов do_some определен так
Код: plaintext
1.
do_some(){throw std::runtime_error("bebe");}

то до строки mutex_.unlock() поток не дойдет.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Может ли другой поток изменить заблокированный мьютексом объект? / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]