Ситуация, где нужны мьютексы? - PullRequest
4 голосов
/ 28 июня 2010

Может кто-нибудь помочь мне с примером ситуации, в которой отсутствие мьютексов "определенно" приводит к неверному результату.

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

- Neeraj

Ответы [ 8 ]

7 голосов
/ 28 июня 2010

Рассмотрим любой правильный код, который использует мьютексы для синхронизации.Сняв блокировку, вы введете в программу новые (возможно, некорректные) поведения (исполнения).Однако новый код будет по-прежнему содержать все старое поведение, поэтому всегда будет хотя бы одно выполнение, которое даст правильный результат.Следовательно, то, что вы просите, невозможно.

2 голосов
/ 28 июня 2010

Создайте программу, в которой есть fork ().Затем заставьте и дочерний процесс, и родительский процесс читать число из одного и того же файла, увеличивать его и затем записывать обратно в файл.Делайте это 100 раз в каждом процессе.

1 голос
/ 28 июня 2010

Вы просто проверяете, что он правильно блокируется?Если так, может быть, что-то подобное?Два потока

#Global Variables
int counter = 1
int factorial = 1


#Critical Section
counter++
Delay for some amount of time
factorial *= counter
#End Critical Section

Если ваш Mutex работает, то конечный результат должен быть 6. В противном случае это будет 9. Редактировать или 3 Полагаю, что *= не атомарный, но6 в любом случае.

1 голос
/ 28 июня 2010

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

0 голосов
/ 28 июня 2010

Вы можете смоделировать известный сценарий "банковского перевода" , используемый для иллюстрации транзакций базы данных.У нас есть аккаунты A и B, и нам нужно перевести 200 баксов с A на B.

C ++ - подобный псевдокоду (не тестировался)

 int accountA = 200;
 int accountB = 0;

 void transfer( int& from, int& to, int amount )
 {
     //mutex acquisition should be here
     if( from < amount ) {
         printf( "error" );
         // mutex release should be here
         return;
     }
     from -= amount;
     Sleep( 5000 ); //wait idle for 5 seconds
     to += amount;
     // mutex release should be here
 }

 void display( const int& account1, const int& account2 )
 {
     //mutex acquisition should be here
     Sleep( 3000 ); //wait 3 seconds
     printf( "%d", account1 );
     printf( %d", account2 );
     // mutex release should be here
 }

теперь порождает два потока и выполняет transfer( accountA, accountB, 200 ); наодин и display( accountA, accountB ); на другом, начинающемся в один и тот же момент времени.

В системе без нагрузки программа покажет, что деньги исчезли «в середине перевода» - счета читаются в середине«транзакция» (проблема здесь нет транзакции), поэтому нет изоляции.С мьютексами вы увидите конечное состояние - «после передачи».

0 голосов
/ 28 июня 2010

Вот тип теста, который я использовал в своем наборе тестов реализации мьютекса:

// global:
enum { HUGE_VAL = 50000 }
Mutex mutex;
int variable;

// main thread
mutex.lock();
thread.run();
for(int i = 0; i < HUGE_VAL; ++i)
    ++variable;
assert(variable == HUGE_VAL);
mutex.unlock();
thread.join();
assert(variable == -HUGE_VAL);

// parallel thread
mutex.lock();
variable = -HUGE_VAL;
mutex.unlock();

Конечно, адаптируйте HUGE_VAL, как вам кажется, потому что мьютекс используется для защиты от одновременного доступа. Поэтому, чтобы проверить это, вам нужно создать параллелизм, и чем быстрее машина, тем больше должно быть HUGE_VAL ...

0 голосов
/ 28 июня 2010

Я думаю, что нет, потому что планировщик, реализованный в современных ОС, не является детерминированным с точки зрения приложения.Однако, если вы запускаете много потоков и тестируете код несколько раз, вероятность конфликта должна быть достаточно высокой.

0 голосов
/ 28 июня 2010

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

Если требуется «определенная ситуация», попросите мужа внести депозит, а затем поспать достаточно времени, чтобы жена могла сделать вывод. Результат мужа перезапишет результат жены, и баланс счета больше не будет КИСЛОТНЫМ.

...