Skip to content

Barriers

Race condition

 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
28
29
30
31
32
33
34
35
36
37
38
39
// Deciding how many bags of chips to buy for the party
#include <mutex>
#include <thread>

unsigned int bags_of_chips = 1;  // start with one on the list
std::mutex pencil;

void cpu_work(unsigned long workUnits) {
  unsigned long x = 0;
  for (unsigned long i; i < workUnits * 1000000; ++i) {
    ++x;
  }
}

void barron_shopper() {
  cpu_work(1);  // do a bit of work first
  std::scoped_lock<std::mutex> lock(pencil);
  bags_of_chips *= 2;
  printf("Barron DOUBLED the bags of chips.\n");
}

void olivia_shopper() {
  cpu_work(1);  // do a bit of work first
  std::scoped_lock<std::mutex> lock(pencil);
  bags_of_chips += 3;
  printf("Olivia ADDED 3 bags of chips.\n");
}

int main() {
  std::thread shoppers[10];
  for (int i = 0; i < 10; i += 2) {
    shoppers[i] = std::thread(barron_shopper);
    shoppers[i + 1] = std::thread(olivia_shopper);
  }
  for (auto& s : shoppers) {
    s.join();
  }
  printf("We need to buy %u bags_of_chips.\n", bags_of_chips);
}

Barrier

 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
28
29
30
31
32
33
34
35
36
37
38
39
// Deciding how many bags of chips to buy for the party
#include <mutex>
#include <thread>

unsigned int bags_of_chips = 1;  // start with one on the list
std::mutex pencil;

void cpu_work(unsigned long workUnits) {
  unsigned long x = 0;
  for (unsigned long i; i < workUnits * 1000000; ++i) {
    ++x;
  }
}

void barron_shopper() {
  cpu_work(1);  // do a bit of work first
  std::scoped_lock<std::mutex> lock(pencil);
  bags_of_chips *= 2;
  printf("Barron DOUBLED the bags of chips.\n");
}

void olivia_shopper() {
  cpu_work(1);  // do a bit of work first
  std::scoped_lock<std::mutex> lock(pencil);
  bags_of_chips += 3;
  printf("Olivia ADDED 3 bags of chips.\n");
}

int main() {
  std::thread shoppers[10];
  for (int i = 0; i < 10; i += 2) {
    shoppers[i] = std::thread(barron_shopper);
    shoppers[i + 1] = std::thread(olivia_shopper);
  }
  for (auto& s : shoppers) {
    s.join();
  }
  printf("We need to buy %u bags_of_chips.\n", bags_of_chips);
}
 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Deciding how many bags of chips to buy for the party
#include <boost/thread/barrier.hpp>
#include <mutex>
#include <thread>

unsigned int bags_of_chips = 1;  // start with one on the list
std::mutex pencil;
boost::barrier fist_bump(10);

void cpu_work(unsigned long workUnits) {
  unsigned long x = 0;
  for (unsigned long i; i < workUnits * 1000000; ++i) {
    ++x;
  }
}

void barron_shopper() {
  cpu_work(1);  // do a bit of work first
  fist_bump.wait();
  std::scoped_lock<std::mutex> lock(pencil);
  bags_of_chips *= 2;
  printf("Barron DOUBLED the bags of chips.\n");
}

void olivia_shopper() {
  cpu_work(1);  // do a bit of work first
  {
    std::scoped_lock<std::mutex> lock(pencil);
    bags_of_chips += 3;
  }
  printf("Olivia ADDED 3 bags of chips.\n");
  fist_bump.wait();
}

int main() {
  std::thread shoppers[10];
  for (int i = 0; i < 10; i += 2) {
    shoppers[i] = std::thread(barron_shopper);
    shoppers[i + 1] = std::thread(olivia_shopper);
  }
  for (auto& s : shoppers) {
    s.join();
  }
  printf("We need to buy %u bags_of_chips.\n", bags_of_chips);
}
 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Deciding how many bags of chips to buy for the party
#include <boost/thread/latch.hpp>
#include <mutex>
#include <thread>

unsigned int bags_of_chips = 1;  // start with one on the list
std::mutex pencil;
boost::latch fist_bump(10);

void cpu_work(unsigned long workUnits) {
  unsigned long x = 0;
  for (unsigned long i; i < workUnits * 1000000; ++i) {
    ++x;
  }
}

void barron_shopper() {
  cpu_work(1);  // do a bit of work first
  fist_bump.wait();
  std::scoped_lock<std::mutex> lock(pencil);
  bags_of_chips *= 2;
  printf("Barron DOUBLED the bags of chips.\n");
}

void olivia_shopper() {
  cpu_work(1);  // do a bit of work first
  {
    std::scoped_lock<std::mutex> lock(pencil);
    bags_of_chips += 3;
  }
  printf("Olivia ADDED 3 bags of chips.\n");
  fist_bump.count_down();
}

int main() {
  std::thread shoppers[10];
  for (int i = 0; i < 10; i += 2) {
    shoppers[i] = std::thread(barron_shopper);
    shoppers[i + 1] = std::thread(olivia_shopper);
  }
  for (auto& s : shoppers) {
    s.join();
  }
  printf("We need to buy %u bags_of_chips.\n", bags_of_chips);
}