Skip to content

3. Mutual Exclusion

Data race

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Two shoppers adding items to a shared notepad
#include <thread>

unsigned int garlic_count = 0;

void shopper() {
  for (int i = 0; i < 10; ++i) {
    ++garlic_count;
  }
}

int main() {
  std::thread barron(shopper);
  std::thread olivia(shopper);
  barron.join();
  olivia.join();
  printf("We should buy %u garlic.\n", garlic_count);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Two shoppers adding items to a shared notepad
#include <thread>

unsigned int garlic_count = 0;

void shopper() {
  for (int i = 0; i < 10000000; ++i) {
    ++garlic_count;
  }
}

int main() {
  std::thread barron(shopper);
  std::thread olivia(shopper);
  barron.join();
  olivia.join();
  printf("We should buy %u garlic.\n", garlic_count);
}

Mutual exclusion

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Two shoppers adding items to a shared notepad

#include <mutex>
#include <thread>

unsigned int garlic_count = 0;
std::mutex pencil;

void shopper() {
  pencil.lock();
  for (int i = 0; i < 10000000; ++i) {
    ++garlic_count;
  }
  pencil.unlock();
}

int main() {
  std::thread barron(shopper);
  std::thread olivia(shopper);
  barron.join();
  olivia.join();
  printf("We should buy %u garlic.\n", garlic_count);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Two shoppers adding items to a shared notepad
*/
#include <chrono>
#include <mutex>
#include <thread>

unsigned int garlic_count = 0;
std::mutex pencil;

void shopper() {
  for (int i = 0; i < 5; ++i) {
    printf("Shopper %d is thinking...\n", std::this_thread::get_id());
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    pencil.lock();
    ++garlic_count;
    pencil.unlock();
  }
}

int main() {
  std::thread barron(shopper);
  std::thread olivia(shopper);
  barron.join();
  olivia.join();
  printf("We should buy %u garlic.\n", garlic_count);
}

Atomic objects

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Two shoppers adding items to a shared notepad
#include <thread>

unsigned int garlic_count = 0;

void shopper() {
  for (int i = 0; i < 10000000; ++i) {
    ++garlic_count;
  }
}

int main() {
  std::thread barron(shopper);
  std::thread olivia(shopper);
  barron.join();
  olivia.join();
  printf("We should buy %u garlic.\n", garlic_count);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// Two shoppers adding items to a shared notepad
#include <atomic>
#include <thread>

std::atomic<unsigned int> garlic_count(0);

void shopper() {
  for (int i = 0; i < 10000000; ++i) {
    ++garlic_count;
  }
}

int main() {
  std::thread barron(shopper);
  std::thread olivia(shopper);
  barron.join();
  olivia.join();
  printf("We should buy %u garlic.\n", garlic_count.load());
}