From 0c296317231550dc8ca158707e0794c19455747e Mon Sep 17 00:00:00 2001 From: Mwsxy Date: Sat, 22 Jan 2022 00:24:33 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/main.cpp b/main.cpp index f4ecab8..8061469 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,11 @@ #include #include #include - +#include +#include +#include +#include +#include struct User { std::string password; @@ -15,12 +19,14 @@ struct User { }; std::map users; -std::map has_login; // 换成 std::chrono::seconds 之类的 +std::map has_login; // 换成 std::chrono::seconds 之类的 +std::shared_mutex users_smtx, has_login_smtx; // 作业要求1:把这些函数变成多线程安全的 // 提示:能正确利用 shared_mutex 加分,用 lock_guard 系列加分 std::string do_register(std::string username, std::string password, std::string school, std::string phone) { User user = {password, school, phone}; + std::unique_lock ugrd(users_smtx); if (users.emplace(username, user).second) return "注册成功"; else @@ -29,21 +35,30 @@ std::string do_register(std::string username, std::string password, std::string std::string do_login(std::string username, std::string password) { // 作业要求2:把这个登录计时器改成基于 chrono 的 - long now = time(NULL); // C 语言当前时间 - if (has_login.find(username) != has_login.end()) { - int sec = now - has_login.at(username); // C 语言算时间差 - return std::to_string(sec) + "秒内登录过"; + { + std::unique_lock ugrd(has_login_smtx); + auto now = std::chrono::steady_clock::now(); // 当前时间 + if (has_login.find(username) != has_login.end()) { + auto dt = now - has_login.at(username); // 时间差 + int sec = std::chrono::duration_cast(dt).count(); + return std::to_string(sec) + "秒内登录过"; + } + has_login[username] = now; + } + { + std::shared_lock sgrd(users_smtx); + if (users.find(username) == users.end()) + return "用户名错误"; + if (users.at(username).password != password) + return "密码错误"; } - has_login[username] = now; - - if (users.find(username) == users.end()) - return "用户名错误"; - if (users.at(username).password != password) - return "密码错误"; return "登录成功"; } std::string do_queryuser(std::string username) { + std::shared_lock sgrd(users_smtx); + if (users.find(username) == users.end()) + return "query用户名错误"; auto &user = users.at(username); std::stringstream ss; ss << "用户名: " << username << std::endl; @@ -54,10 +69,29 @@ std::string do_queryuser(std::string username) { struct ThreadPool { + std::list pool; + void create(std::function start) { // 作业要求3:如何让这个线程保持在后台执行不要退出? // 提示:改成 async 和 future 且用法正确也可以加分 std::thread thr(start); + pool.push_back(std::move(thr)); + } + void wait_finish() { + auto pt = pool.begin(); + while (!pool.empty()) { + if (pt->joinable()) { + pt->join(); + pt = pool.erase(pt); + } + else { + pt++; + if (pt==pool.end()) pt = pool.begin(); + } + } + } + ~ThreadPool() { + wait_finish(); } }; @@ -72,7 +106,7 @@ std::string phone[] = {"110", "119", "120", "12315"}; } int main() { - for (int i = 0; i < 262144; i++) { + for (int i = 0; i < (262144>>8); i++) { tpool.create([&] { std::cout << do_register(test::username[rand() % 4], test::password[rand() % 4], test::school[rand() % 4], test::phone[rand() % 4]) << std::endl; }); From 86cf5aa4615daebcf0bce5d840a7e0b78a516097 Mon Sep 17 00:00:00 2001 From: Mwsxy Date: Sat, 22 Jan 2022 00:32:39 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=B8=8B=E9=94=81?= =?UTF-8?q?=E7=9A=84=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/main.cpp b/main.cpp index 8061469..e3ce82a 100644 --- a/main.cpp +++ b/main.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include struct User { @@ -36,14 +35,19 @@ std::string do_register(std::string username, std::string password, std::string std::string do_login(std::string username, std::string password) { // 作业要求2:把这个登录计时器改成基于 chrono 的 { - std::unique_lock ugrd(has_login_smtx); auto now = std::chrono::steady_clock::now(); // 当前时间 - if (has_login.find(username) != has_login.end()) { - auto dt = now - has_login.at(username); // 时间差 - int sec = std::chrono::duration_cast(dt).count(); - return std::to_string(sec) + "秒内登录过"; + { + std::shared_lock sgrd(has_login_smtx); + if (has_login.find(username) != has_login.end()) { + auto dt = now - has_login.at(username); // 时间差 + int sec = std::chrono::duration_cast(dt).count(); + return std::to_string(sec) + "秒内登录过"; + } + } + { + std::unique_lock ugrd(has_login_smtx); + has_login[username] = now; } - has_login[username] = now; } { std::shared_lock sgrd(users_smtx); @@ -58,7 +62,7 @@ std::string do_login(std::string username, std::string password) { std::string do_queryuser(std::string username) { std::shared_lock sgrd(users_smtx); if (users.find(username) == users.end()) - return "query用户名错误"; + return "query:用户名错误"; auto &user = users.at(username); std::stringstream ss; ss << "用户名: " << username << std::endl; @@ -106,7 +110,7 @@ std::string phone[] = {"110", "119", "120", "12315"}; } int main() { - for (int i = 0; i < (262144>>8); i++) { + for (int i = 0; i < 262144; i++) { tpool.create([&] { std::cout << do_register(test::username[rand() % 4], test::password[rand() % 4], test::school[rand() % 4], test::phone[rand() % 4]) << std::endl; });