lab1 code
This commit is contained in:
208
.clang-format
Normal file
208
.clang-format
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
BasedOnStyle: ''
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentRequiresClause: true
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertBraces: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PointerAlignment: Right
|
||||||
|
PPIndentWidth: -1
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterOverloadedOperator: false
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
60
.vscode/settings.json
vendored
Normal file
60
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"numbers": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"syncstream": "cpp",
|
||||||
|
"csignal": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"fstream": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
lab1/.gitignore
vendored
Normal file
1
lab1/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
build/
|
||||||
@@ -3,7 +3,7 @@ OUT_BIN := $(OUT_DIR)/banker
|
|||||||
|
|
||||||
$(OUT_BIN): banker.cpp
|
$(OUT_BIN): banker.cpp
|
||||||
mkdir -p $(OUT_DIR)
|
mkdir -p $(OUT_DIR)
|
||||||
g++ -pthread banker.cpp -o $(OUT_BIN)
|
g++ -pthread --std=c++20 banker.cpp -o $(OUT_BIN)
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: $(OUT_BIN)
|
run: $(OUT_BIN)
|
||||||
|
|||||||
183
lab1/banker.cpp
183
lab1/banker.cpp
@@ -1,22 +1,19 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <thread>
|
|
||||||
#include <deque>
|
|
||||||
#include <vector>
|
|
||||||
#include <chrono>
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <csignal>
|
||||||
|
#include <deque>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <semaphore>
|
#include <semaphore>
|
||||||
|
#include <sstream>
|
||||||
|
#include <syncstream>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define TELLER_NUM 5
|
#define TELLER_NUM 3
|
||||||
#define TIME_GRAN_MSEC 200
|
#define TIME_GRAN_MSEC 200
|
||||||
|
|
||||||
std::atomic<bool> bank_open = false;
|
|
||||||
std::mutex custom_q_mtx;
|
|
||||||
std::counting_semaphore custom_num_sem;
|
|
||||||
|
|
||||||
std::deque<Customer> customer_q;
|
|
||||||
|
|
||||||
|
|
||||||
struct CustomerInfo {
|
struct CustomerInfo {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
unsigned int arrival_time;
|
unsigned int arrival_time;
|
||||||
@@ -28,42 +25,164 @@ struct Customer {
|
|||||||
unsigned int service_time;
|
unsigned int service_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
void teller_thread(int id, std::chrono::time_point<std::chrono::steady_clock> start_tick) {
|
std::atomic<bool> bank_open{false};
|
||||||
std::cout << "Teller id " << id << " started\n";
|
std::mutex customer_q_mtx;
|
||||||
|
std::counting_semaphore<100> customer_num_sem{0};
|
||||||
|
|
||||||
|
std::deque<Customer> customer_q;
|
||||||
|
|
||||||
|
void signal_handler(int signum) {
|
||||||
|
// std::cout << "\nReceived signal " << signum << ", stopping...\n";
|
||||||
|
write(STDOUT_FILENO, "\nCaught SIGINT, shutting down...\n", 33);
|
||||||
|
bank_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void teller_thread(
|
||||||
|
int id, std::chrono::time_point<std::chrono::steady_clock> start_tick) {
|
||||||
|
std::osyncstream(std::cout)
|
||||||
|
<< "Teller id " << id << " started" << std::endl;
|
||||||
std::chrono::time_point curr_tick = start_tick;
|
std::chrono::time_point curr_tick = start_tick;
|
||||||
|
unsigned int tick_count = 0;
|
||||||
bool is_serving = false;
|
bool is_serving = false;
|
||||||
std::chrono::time_point<std::chrono::steady_clock> start_serving_time;
|
std::chrono::time_point<std::chrono::steady_clock> start_serving_time;
|
||||||
struct Customer curr_customer;
|
struct Customer curr_customer;
|
||||||
while (bank_open) {
|
while (bank_open) {
|
||||||
if (is_serving && ((curr_tick - start_serving_time) / TIME_GRAN_MSEC) >= curr_customer.service_time) {
|
if (is_serving) {
|
||||||
|
if ((std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
(curr_tick - start_serving_time) / TIME_GRAN_MSEC))
|
||||||
|
.count() <= curr_customer.service_time) {
|
||||||
|
// We are still serving, do nothing
|
||||||
|
std::osyncstream(std::cout) << "Teller id " << id << " is serving customer " << curr_customer.id << " at tick " << tick_count << std::endl;
|
||||||
|
goto next_tick;
|
||||||
|
} else {
|
||||||
|
// We have just finished serving.
|
||||||
|
std::osyncstream(std::cout) << "Teller id " << id << " finishied serving customer " << curr_customer.id << " at tick " << tick_count << std::endl;
|
||||||
|
is_serving = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::cout << "Teller id " << id << " waiting request\n";
|
|
||||||
|
|
||||||
|
|
||||||
|
// Try to acquire a new customer
|
||||||
|
if (customer_num_sem.try_acquire()) {
|
||||||
|
// Successfully acquired a customer
|
||||||
|
std::lock_guard<std::mutex> lock(customer_q_mtx);
|
||||||
|
if (!customer_q.empty()) {
|
||||||
|
curr_customer = customer_q.front();
|
||||||
|
customer_q.pop_front();
|
||||||
|
|
||||||
|
std::osyncstream(std::cout)
|
||||||
|
<< "Teller id " << id << " is now serving customer "
|
||||||
|
<< curr_customer.id << " for " << curr_customer.service_time
|
||||||
|
<< " ticks at tick " << tick_count << std::endl;
|
||||||
|
|
||||||
|
is_serving = true;
|
||||||
|
start_serving_time = curr_tick;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::osyncstream(std::cout)
|
||||||
|
<< "Teller id " << id << " is idle at tick " << tick_count << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_tick:
|
||||||
|
++tick_count;
|
||||||
curr_tick += std::chrono::milliseconds(TIME_GRAN_MSEC);
|
curr_tick += std::chrono::milliseconds(TIME_GRAN_MSEC);
|
||||||
std::this_thread::sleep_until(curr_tick);
|
std::this_thread::sleep_until(curr_tick);
|
||||||
}
|
}
|
||||||
std::cout << "Teller id " << id << " closing\n";
|
std::osyncstream(std::cout)
|
||||||
|
<< "Teller id " << id << " closing" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
void customer_thread(
|
||||||
bank_open = true;
|
CustomerInfo info,
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> start_tick) {
|
||||||
|
|
||||||
std::vector<std::thread> tellers;
|
Customer cus{.id = info.id, .service_time = info.service_time};
|
||||||
for (int i = 0; i < TELLER_NUM; ++i) {
|
|
||||||
try {
|
std::chrono::time_point curr_tick = start_tick;
|
||||||
tellers.emplace_back(teller_thread, i);
|
unsigned int tick_count = 0;
|
||||||
} catch (const std::system_error& e) {
|
std::chrono::time_point target_tick = start_tick + std::chrono::milliseconds(TIME_GRAN_MSEC) * info.arrival_time;
|
||||||
std::cerr << "Failed to create thread, i = " << i << ": " << e.what() << '\n';
|
while (curr_tick < target_tick) {
|
||||||
|
if (!bank_open) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++tick_count;
|
||||||
|
curr_tick += std::chrono::milliseconds(TIME_GRAN_MSEC);
|
||||||
|
std::this_thread::sleep_until(curr_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wake up and push self into queue, then V(customer_num_sem)
|
||||||
|
std::osyncstream(std::cout) << "Customer id " << info.id << " arrived at tick " << tick_count << std::endl;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(customer_q_mtx);
|
||||||
|
customer_q.push_back(cus);
|
||||||
|
}
|
||||||
|
customer_num_sem.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cout << "Invalid commandline arg, expected filename";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
// Read config from file
|
||||||
|
std::vector<CustomerInfo> customer_infos;
|
||||||
|
|
||||||
|
std::ifstream file(argv[1]);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
std::cerr << "Cannot open file: " << argv[1] << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
std::istringstream iss(line);
|
||||||
|
CustomerInfo cus;
|
||||||
|
if (iss >> cus.id >> cus.arrival_time >> cus.service_time) {
|
||||||
|
customer_infos.push_back(cus);
|
||||||
|
} else {
|
||||||
|
std::cerr << "Invalid line: " << line << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5 * TIME_GRAN_MSEC));
|
file.close();
|
||||||
std::cout << "Closing all child\n";
|
|
||||||
bank_open = false;
|
|
||||||
|
|
||||||
for (auto& t : tellers) {
|
bank_open = true;
|
||||||
|
std::chrono::time_point start_tick = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
// Set up tellers
|
||||||
|
std::vector<std::thread> tellers;
|
||||||
|
|
||||||
|
for (int i = 0; i < TELLER_NUM; ++i) {
|
||||||
|
try {
|
||||||
|
tellers.emplace_back(teller_thread, i, start_tick);
|
||||||
|
}
|
||||||
|
catch (const std::system_error &e) {
|
||||||
|
std::cerr << "Failed to create teller thread, i = " << i << ": "
|
||||||
|
<< e.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up customers
|
||||||
|
std::vector<std::thread> customers;
|
||||||
|
for (auto cu : customer_infos) {
|
||||||
|
try {
|
||||||
|
customers.emplace_back(customer_thread, cu, start_tick);
|
||||||
|
} catch (const std::system_error &e) {
|
||||||
|
std::cerr << "Failed to create customer thread, id = " << cu.id << ": "
|
||||||
|
<< e.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all children to shutdown (by ctrl-c handler)
|
||||||
|
for (auto &t: customers) {
|
||||||
|
if (t.joinable()) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : tellers) {
|
||||||
if (t.joinable()) {
|
if (t.joinable()) {
|
||||||
t.join();
|
t.join();
|
||||||
}
|
}
|
||||||
|
|||||||
71
lab1/test_data/1_out.txt
Normal file
71
lab1/test_data/1_out.txt
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
Teller id 0 started
|
||||||
|
Teller id 1 started
|
||||||
|
Teller id 1 is idle at tick 0
|
||||||
|
Teller id 0 is idle at tick 0
|
||||||
|
Teller id 2 started
|
||||||
|
Teller id 2 is idle at tick 0
|
||||||
|
Teller id 0 is idle at tick 1
|
||||||
|
Teller id 2 is idle at tick 1
|
||||||
|
Teller id 1 is idle at tick 1
|
||||||
|
Customer id 1 arrived at tick 1
|
||||||
|
Teller id 0 is now serving customer 1 for 10 ticks at tick 2
|
||||||
|
Teller id 1 is idle at tick 2
|
||||||
|
Teller id 2 is idle at tick 2
|
||||||
|
Teller id 0 is serving customer 1 at tick 3
|
||||||
|
Teller id 1 is idle at tick 3
|
||||||
|
Teller id 2 is idle at tick 3
|
||||||
|
Teller id 0 is serving customer 1 at tick 4
|
||||||
|
Teller id 1 is idle at tick 4
|
||||||
|
Teller id 2 is idle at tick 4
|
||||||
|
Teller id 0 is serving customer 1 at tick 5
|
||||||
|
Customer id 2 arrived at tick 5
|
||||||
|
Teller id 2 is idle at tick 5
|
||||||
|
Teller id 1 is idle at tick 5
|
||||||
|
Teller id 0 is serving customer 1 at tick 6
|
||||||
|
Teller id 2 is now serving customer 2 for 2 ticks at tick 6
|
||||||
|
Customer id 3 arrived at tick 6
|
||||||
|
Teller id 1 is idle at tick 6
|
||||||
|
Teller id 0 is serving customer 1 at tick 7
|
||||||
|
Teller id 1 is now serving customer 3 for 3 ticks at tick 7
|
||||||
|
Teller id 2 is serving customer 2 at tick 7
|
||||||
|
Teller id 0 is serving customer 1 at tick 8
|
||||||
|
Teller id 1 is serving customer 3 at tick 8
|
||||||
|
Teller id 2 is serving customer 2 at tick 8
|
||||||
|
Teller id 0 is serving customer 1 at tick 9
|
||||||
|
Teller id 1 is serving customer 3 at tick 9
|
||||||
|
Teller id 2 finishied serving customer 2 at tick 9
|
||||||
|
Teller id 2 is idle at tick 9
|
||||||
|
Teller id 1 is serving customer 3 at tick 10
|
||||||
|
Teller id 0 is serving customer 1 at tick 10
|
||||||
|
Teller id 2 is idle at tick 10
|
||||||
|
Teller id 0 is serving customer 1 at tick 11
|
||||||
|
Teller id 1 finishied serving customer 3 at tick 11
|
||||||
|
Teller id 2 is idle at tick 11
|
||||||
|
Teller id 1 is idle at tick 11
|
||||||
|
Teller id 1 is idle at tick 12
|
||||||
|
Teller id 2 is idle at tick 12
|
||||||
|
Teller id 0 is serving customer 1 at tick 12
|
||||||
|
Teller id 0 finishied serving customer 1 at tick 13
|
||||||
|
Teller id 0 is idle at tick 13
|
||||||
|
Teller id 2 is idle at tick 13
|
||||||
|
Teller id 1 is idle at tick 13
|
||||||
|
Teller id 0 is idle at tick 14
|
||||||
|
Teller id 1 is idle at tick 14
|
||||||
|
Teller id 2 is idle at tick 14
|
||||||
|
Teller id 0 is idle at tick 15
|
||||||
|
Teller id 2 is idle at tick 15
|
||||||
|
Teller id 1 is idle at tick 15
|
||||||
|
Teller id 0 is idle at tick 16
|
||||||
|
Teller id 1 is idle at tick 16
|
||||||
|
Teller id 2 is idle at tick 16
|
||||||
|
Teller id 2 is idle at tick 17
|
||||||
|
Teller id 0 is idle at tick 17
|
||||||
|
Teller id 1 is idle at tick 17
|
||||||
|
Teller id 0 is idle at tick 18
|
||||||
|
Teller id 1 is idle at tick 18
|
||||||
|
Teller id 2 is idle at tick 18
|
||||||
|
^C
|
||||||
|
Caught SIGINT, shutting down...
|
||||||
|
Teller id 0 closing
|
||||||
|
Teller id 1 closing
|
||||||
|
Teller id 2 closing
|
||||||
7
lab1/test_data/2.txt
Normal file
7
lab1/test_data/2.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
1 1 10
|
||||||
|
2 2 10
|
||||||
|
3 3 10
|
||||||
|
4 4 10
|
||||||
|
5 5 5
|
||||||
|
6 6 7
|
||||||
|
8 7 10
|
||||||
130
lab1/test_data/2_out.txt
Normal file
130
lab1/test_data/2_out.txt
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
Teller id 1 started
|
||||||
|
Teller id 0 started
|
||||||
|
Teller id 2 started
|
||||||
|
Teller id 1 is idle at tick 0
|
||||||
|
Teller id 2 is idle at tick 0
|
||||||
|
Teller id 0 is idle at tick 0
|
||||||
|
Teller id 0 is idle at tick 1
|
||||||
|
Teller id 2 is idle at tick 1
|
||||||
|
Teller id 1 is idle at tick 1
|
||||||
|
Customer id 1 arrived at tick 1
|
||||||
|
Teller id 0 is now serving customer 1 for 10 ticks at tick 2
|
||||||
|
Teller id 1 is idle at tick 2
|
||||||
|
Teller id 2 is idle at tick 2
|
||||||
|
Customer id 2 arrived at tick 2
|
||||||
|
Teller id 1 is now serving customer 2 for 10 ticks at tick 3
|
||||||
|
Customer id 3 arrived at tick 3
|
||||||
|
Teller id 0 is serving customer 1 at tick 3
|
||||||
|
Teller id 2 is idle at tick 3
|
||||||
|
Teller id 0 is serving customer 1 at tick 4
|
||||||
|
Teller id 2 is now serving customer 3 for 10 ticks at tick 4
|
||||||
|
Teller id 1 is serving customer 2 at tick 4
|
||||||
|
Customer id 4 arrived at tick 4
|
||||||
|
Teller id 0 is serving customer 1 at tick 5
|
||||||
|
Teller id 2 is serving customer 3 at tick 5
|
||||||
|
Teller id 1 is serving customer 2 at tick 5
|
||||||
|
Customer id 5 arrived at tick 5
|
||||||
|
Customer id 6 arrived at tick 6
|
||||||
|
Teller id 1 is serving customer 2 at tick 6
|
||||||
|
Teller id 0 is serving customer 1 at tick 6
|
||||||
|
Teller id 2 is serving customer 3 at tick 6
|
||||||
|
Teller id 1 is serving customer 2 at tick 7
|
||||||
|
Teller id 0 is serving customer 1 at tick 7
|
||||||
|
Customer id 8 arrived at tick 7
|
||||||
|
Teller id 2 is serving customer 3 at tick 7
|
||||||
|
Teller id 1 is serving customer 2 at tick 8
|
||||||
|
Teller id 2 is serving customer 3 at tick 8
|
||||||
|
Teller id 0 is serving customer 1 at tick 8
|
||||||
|
Teller id 2 is serving customer 3 at tick 9
|
||||||
|
Teller id 1 is serving customer 2 at tick 9
|
||||||
|
Teller id 0 is serving customer 1 at tick 9
|
||||||
|
Teller id 0 is serving customer 1 at tick 10
|
||||||
|
Teller id 2 is serving customer 3 at tick 10
|
||||||
|
Teller id 1 is serving customer 2 at tick 10
|
||||||
|
Teller id 2 is serving customer 3 at tick 11
|
||||||
|
Teller id 1 is serving customer 2 at tick 11
|
||||||
|
Teller id 0 is serving customer 1 at tick 11
|
||||||
|
Teller id 1 is serving customer 2 at tick 12
|
||||||
|
Teller id 2 is serving customer 3 at tick 12
|
||||||
|
Teller id 0 is serving customer 1 at tick 12
|
||||||
|
Teller id 2 is serving customer 3 at tick 13
|
||||||
|
Teller id 1 is serving customer 2 at tick 13
|
||||||
|
Teller id 0 finishied serving customer 1 at tick 13
|
||||||
|
Teller id 0 is now serving customer 4 for 10 ticks at tick 13
|
||||||
|
Teller id 2 is serving customer 3 at tick 14
|
||||||
|
Teller id 1 finishied serving customer 2 at tick 14
|
||||||
|
Teller id 1 is now serving customer 5 for 5 ticks at tick 14
|
||||||
|
Teller id 0 is serving customer 4 at tick 14
|
||||||
|
Teller id 2 finishied serving customer 3 at tick 15
|
||||||
|
Teller id 2 is now serving customer 6 for 7 ticks at tick 15
|
||||||
|
Teller id 1 is serving customer 5 at tick 15
|
||||||
|
Teller id 0 is serving customer 4 at tick 15
|
||||||
|
Teller id 2 is serving customer 6 at tick 16
|
||||||
|
Teller id 1 is serving customer 5 at tick 16
|
||||||
|
Teller id 0 is serving customer 4 at tick 16
|
||||||
|
Teller id 2 is serving customer 6 at tick 17
|
||||||
|
Teller id 0 is serving customer 4 at tick 17
|
||||||
|
Teller id 1 is serving customer 5 at tick 17
|
||||||
|
Teller id 2 is serving customer 6 at tick 18
|
||||||
|
Teller id 1 is serving customer 5 at tick 18
|
||||||
|
Teller id 0 is serving customer 4 at tick 18
|
||||||
|
Teller id 2 is serving customer 6 at tick 19
|
||||||
|
Teller id 0 is serving customer 4 at tick 19
|
||||||
|
Teller id 1 is serving customer 5 at tick 19
|
||||||
|
Teller id 0 is serving customer 4 at tick 20
|
||||||
|
Teller id 1 finishied serving customer 5 at tick 20
|
||||||
|
Teller id 1 is now serving customer 8 for 10 ticks at tick 20
|
||||||
|
Teller id 2 is serving customer 6 at tick 20
|
||||||
|
Teller id 1 is serving customer 8 at tick 21
|
||||||
|
Teller id 0 is serving customer 4 at tick 21
|
||||||
|
Teller id 2 is serving customer 6 at tick 21
|
||||||
|
Teller id 2 is serving customer 6 at tick 22
|
||||||
|
Teller id 1 is serving customer 8 at tick 22
|
||||||
|
Teller id 0 is serving customer 4 at tick 22
|
||||||
|
Teller id 1 is serving customer 8 at tick 23
|
||||||
|
Teller id 2 finishied serving customer 6 at tick 23
|
||||||
|
Teller id 2 is idle at tick 23
|
||||||
|
Teller id 0 is serving customer 4 at tick 23
|
||||||
|
Teller id 1 is serving customer 8 at tick 24
|
||||||
|
Teller id 0 finishied serving customer 4 at tick 24
|
||||||
|
Teller id 2 is idle at tick 24
|
||||||
|
Teller id 0 is idle at tick 24
|
||||||
|
Teller id 1 is serving customer 8 at tick 25
|
||||||
|
Teller id 2 is idle at tick 25
|
||||||
|
Teller id 0 is idle at tick 25
|
||||||
|
Teller id 1 is serving customer 8 at tick 26
|
||||||
|
Teller id 2 is idle at tick 26
|
||||||
|
Teller id 0 is idle at tick 26
|
||||||
|
Teller id 1 is serving customer 8 at tick 27
|
||||||
|
Teller id 0 is idle at tick 27
|
||||||
|
Teller id 2 is idle at tick 27
|
||||||
|
Teller id 1 is serving customer 8 at tick 28
|
||||||
|
Teller id 2 is idle at tick 28
|
||||||
|
Teller id 0 is idle at tick 28
|
||||||
|
Teller id 1 is serving customer 8 at tick 29
|
||||||
|
Teller id 2 is idle at tick 29
|
||||||
|
Teller id 0 is idle at tick 29
|
||||||
|
Teller id 1 is serving customer 8 at tick 30
|
||||||
|
Teller id 0 is idle at tick 30
|
||||||
|
Teller id 2 is idle at tick 30
|
||||||
|
Teller id 1 finishied serving customer 8 at tick 31
|
||||||
|
Teller id 1 is idle at tick 31
|
||||||
|
Teller id 0 is idle at tick 31
|
||||||
|
Teller id 2 is idle at tick 31
|
||||||
|
Teller id 1 is idle at tick 32
|
||||||
|
Teller id 2 is idle at tick 32
|
||||||
|
Teller id 0 is idle at tick 32
|
||||||
|
Teller id 1 is idle at tick 33
|
||||||
|
Teller id 2 is idle at tick 33
|
||||||
|
Teller id 0 is idle at tick 33
|
||||||
|
Teller id 0 is idle at tick 34
|
||||||
|
Teller id 1 is idle at tick 34
|
||||||
|
Teller id 2 is idle at tick 34
|
||||||
|
Teller id 0 is idle at tick 35
|
||||||
|
Teller id 1 is idle at tick 35
|
||||||
|
Teller id 2 is idle at tick 35
|
||||||
|
^C
|
||||||
|
Caught SIGINT, shutting down...
|
||||||
|
Teller id 1 closing
|
||||||
|
Teller id 0 closing
|
||||||
|
Teller id 2 closing
|
||||||
Reference in New Issue
Block a user