Skip to content

Commit 777370b

Browse files
author
Lisa Julia Nebel
committed
Add exapmle for std::latch
1 parent e7da56c commit 777370b

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
assemble_teams_using_latch

Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Compiler settings and get all binaries
2+
CXX = g++
3+
CXXFLAGS = -std=c++20 -Wall
4+
SRC = $(wildcard *.cc)
5+
BIN = $(SRC:.cc=)
6+
7+
# Rules
8+
default: assemble_teams_using_latch
9+
10+
assemble_teams_using_latch: assemble_teams_using_latch.cc
11+
$(CXX) $(CXXFLAGS) -o assemble_teams_using_latch assemble_teams_using_latch.cc
12+
clean:
13+
@$(RM) $(BIN)
14+
15+
16+
# Declare that the targets default and clean are not actual files
17+
.PHONY: default clean

assemble_teams_using_latch.cc

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <algorithm>
2+
#include <chrono>
3+
#include <iostream>
4+
#include <latch>
5+
#include <memory>
6+
#include <random>
7+
#include <thread>
8+
#include <vector>
9+
10+
std::random_device rd; // Non-deterministic random number generator
11+
std::mt19937 gen(rd()); // Seed the generator
12+
std::uniform_int_distribution<> dist(1, 5); // Distribution for random wait time
13+
14+
class TeamManager {
15+
public:
16+
TeamManager(int team_size, int number_of_teams)
17+
: team_size_(team_size)
18+
, number_of_teams_(number_of_teams)
19+
{
20+
latches_.reserve(number_of_teams_);
21+
for (int i = 0; i < number_of_teams_; ++i) {
22+
auto latch = std::make_shared<std::latch>(team_size_);
23+
latches_.push_back(latch);
24+
}
25+
}
26+
27+
void member_arrives(int member_id, int team_id) {
28+
// Assign member to the chosen team, starting from team 1 to 4
29+
std::cout << "Member " << member_id << " is assigned to Team " << team_id + 1 << "." << std::endl;
30+
latches_[team_id]->count_down();
31+
}
32+
33+
void wait_for_teams() {
34+
std::for_each(latches_.begin(), latches_.end(), [](const auto& latch) { latch->wait(); });
35+
}
36+
37+
private:
38+
int team_size_;
39+
int number_of_teams_;
40+
std::vector<std::shared_ptr<std::latch>> latches_;
41+
};
42+
43+
void member_thread(TeamManager& manager, int member_id, int team_id) {
44+
auto waitingTime = dist(gen);
45+
std::cout << "Member " << member_id << " is on the way... that will take " << waitingTime << " s." << std::endl;
46+
// Simulate random travel time
47+
std::this_thread::sleep_for(std::chrono::seconds(waitingTime));
48+
49+
manager.member_arrives(member_id, team_id);
50+
}
51+
52+
int main() {
53+
const int team_size = 3; // Number of members required per team
54+
const int number_of_teams = 4; // Number of teams
55+
56+
TeamManager manager(team_size, number_of_teams);
57+
58+
std::cout << "Calling the team members..." << std::endl;
59+
60+
// Create threads for members arriving
61+
std::vector<std::thread> members;
62+
for (int i = 0; i < team_size * number_of_teams; ++i) {
63+
members.emplace_back(member_thread, std::ref(manager), i + 1, i % number_of_teams);
64+
}
65+
66+
std::cout << "Waiting for all team members to arrive and get assigned..." << std::endl;
67+
// Manager starts to wait, since now the "members are in the pipeline"
68+
manager.wait_for_teams();
69+
70+
// Join all member threads, i.e. start the actual arrival process, concurrently for all members
71+
for (auto& member : members) {
72+
member.join();
73+
}
74+
75+
std::cout << "All teams are ready to play! The game begins!" << std::endl;
76+
77+
return 0;
78+
}

0 commit comments

Comments
 (0)