diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..38f7d0a --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "compilerPath": "C:\\Program Files\\mingw64\\bin\\gcc.exe", + "cStandard": "c23", + "cppStandard": "c++17", + "intelliSenseMode": "gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5c7247b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,7 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6848ac3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,77 @@ +{ + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "optional": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp", + "cfenv": "cpp", + "map": "cpp", + "chrono": "cpp", + "codecvt": "cpp", + "ctime": "cpp", + "ratio": "cpp", + "iomanip": "cpp", + "bitset": "cpp", + "variant": "cpp", + "typeindex": "cpp", + "charconv": "cpp", + "cinttypes": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstring": "cpp", + "cuchar": "cpp", + "forward_list": "cpp", + "list": "cpp", + "unordered_set": "cpp", + "functional": "cpp", + "iterator": "cpp", + "numeric": "cpp", + "random": "cpp", + "regex": "cpp", + "set": "cpp", + "future": "cpp", + "mutex": "cpp", + "scoped_allocator": "cpp", + "shared_mutex": "cpp", + "thread": "cpp", + "valarray": "cpp" + }, + "C_Cpp.errorSquiggles": "disabled" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ae3a634 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,30 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++.exe build active file", + "command": "C:\\Program Files\\mingw64\\bin\\g++.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe", + "-std=c++2a", + "-pthread" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "compiler: \"C:\\Program Files\\mingw64\\bin\\g++.exe\"" + } + ] +} \ No newline at end of file diff --git a/main.cpp b/main.cpp index f4ecab8..68807cd 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,9 @@ #include #include #include - +#include +#include +#include struct User { std::string password; @@ -15,55 +17,80 @@ struct User { }; std::map users; +std::shared_mutex mtx1; + std::map has_login; // 换成 std::chrono::seconds 之类的 +std::shared_mutex mtx2; // 作业要求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}; - if (users.emplace(username, user).second) + std::shared_lock lck1(mtx1); + if (users.emplace(username, user).second){ + std::cout << username << std::endl; return "注册成功"; + } else return "用户名已被注册"; + lck1.unlock(); } std::string do_login(std::string username, std::string password) { // 作业要求2:把这个登录计时器改成基于 chrono 的 - long now = time(NULL); // C 语言当前时间 + std::unique_lock lck2(mtx2); + + auto now_chrono = std::chrono::steady_clock::now(); + auto utc_now = std::chrono::time_point_cast(now_chrono); + auto timestamp = utc_now.time_since_epoch().count(); + long now = static_cast(timestamp); + if (has_login.find(username) != has_login.end()) { - int sec = now - has_login.at(username); // C 语言算时间差 + long sec = now - has_login.at(username); // C 语言算时间差 + return std::to_string(sec) + "秒内登录过"; } has_login[username] = now; + lck2.unlock(); + std::shared_lock lck3(mtx1); if (users.find(username) == users.end()) return "用户名错误"; if (users.at(username).password != password) return "密码错误"; return "登录成功"; + mtx1.unlock_shared(); } std::string do_queryuser(std::string username) { + std::shared_lock lck4(mtx1); auto &user = users.at(username); std::stringstream ss; ss << "用户名: " << username << std::endl; ss << "学校:" << user.school << std::endl; ss << "电话: " << user.phone << std::endl; return ss.str(); + mtx1.unlock_shared(); } - struct ThreadPool { + std::vector m_pool; +public: void create(std::function start) { // 作业要求3:如何让这个线程保持在后台执行不要退出? // 提示:改成 async 和 future 且用法正确也可以加分 std::thread thr(start); + m_pool.push_back(std::move(thr)); + } + ~ThreadPool(){ + for (auto &t :m_pool) { + t.join(); + } } }; ThreadPool tpool; - namespace test { // 测试用例?出水用力! std::string username[] = {"张心欣", "王鑫磊", "彭于斌", "胡原名"}; std::string password[] = {"hellojob", "anti-job42", "cihou233", "reCihou_!"}; @@ -72,7 +99,7 @@ std::string phone[] = {"110", "119", "120", "12315"}; } int main() { - for (int i = 0; i < 262144; i++) { + for (int i = 0; i < 2; 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; }); @@ -83,7 +110,6 @@ int main() { std::cout << do_queryuser(test::username[rand() % 4]) << std::endl; }); } - // 作业要求4:等待 tpool 中所有线程都结束后再退出 return 0; }