forked from parallel101/hw05
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
129 lines (109 loc) · 4.04 KB
/
main.cpp
File metadata and controls
129 lines (109 loc) · 4.04 KB
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 小彭老师作业05:假装是多线程 HTTP 服务器 - 富连网大厂面试官觉得很赞
#include <functional>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <string>
#include <thread>
#include <map>
#include <utility>
#include <shared_mutex>
#include <chrono>
#include <mutex>
#include <future>
struct User {
std::string password;
std::string school;
std::string phone;
};
std::map<std::string, User> users;
std::map<std::string, decltype(std::chrono::steady_clock::now())> has_login; // 换成 std::chrono::seconds 之类的
std::shared_mutex sm;
std::shared_mutex sm_login;
// 作业要求1:把这些函数变成多线程安全的
// 提示:能正确利用 shared_mutex 加分,用 lock_guard 系列加分
std::string do_register(std::string username, std::string password, std::string school, std::string phone) {
User user = {std::move(password), std::move(school), std::move(phone)};
std::unique_lock grd(sm);
if (users.emplace(username, user).second)
return "注册成功";
else
return "用户名已被注册";
}
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) + "秒内登录过";
// }
// has_login[username] = now;
std::shared_lock grd_log_sl(sm_login);
// auto find=;
auto now=std::chrono::steady_clock::now();
if (has_login.find(username) != has_login.end()) {
auto sec=now-has_login.at(username);
using double_s=std::chrono::duration<double>;
double s=std::chrono::duration_cast<double_s>(sec).count();
return std::to_string(s) + "秒内登录过";
}
grd_log_sl.unlock();
std::unique_lock grd_log(sm_login);
has_login[username] = now;
grd_log.unlock();
std::shared_lock grd(sm);
if (users.find(username) == users.end())
return "用户名错误";
if (users.at(username).password != password)
return "密码错误";
return "登录成功";
}
std::string do_queryuser(std::string username) {
std::stringstream ss;
try {
std::shared_lock grd(sm);
auto &user = users.at(username);
grd.unlock();
ss << "用户名: " << username << std::endl;
ss << "学校:" << user.school << std::endl;
ss << "电话: " << user.phone << std::endl;
}
catch (...) {
std::cout<<"username: "<<username<<"not found! "<<'\n';
}
return ss.str();
}
struct ThreadPool {
void create(std::function<void()> start) {
// 作业要求3:如何让这个线程保持在后台执行不要退出?
// 提示:改成 async 和 future 且用法正确也可以加分
// std::thread thr(start);
fts.push_back(std::async(start));
}
std::vector<std::future<void>> fts;
};
ThreadPool tpool;
namespace test { // 测试用例?出水用力!
std::string username[] = {"张心欣", "王鑫磊", "彭于斌", "胡原名"};
std::string password[] = {"hellojob", "anti-job42", "cihou233", "reCihou_!"};
std::string school[] = {"九百八十五大鞋", "浙江大鞋", "剑桥大鞋", "麻绳理工鞋院"};
std::string phone[] = {"110", "119", "120", "12315"};
}
int main() {
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;
});
tpool.create([&] {
std::cout << do_login(test::username[rand() % 4], test::password[rand() % 4]) << std::endl;
});
tpool.create([&] {
std::cout << do_queryuser(test::username[rand() % 4]) << std::endl;
});
}
// 作业要求4:等待 tpool 中所有线程都结束后再退出
for (auto &ret:tpool.fts) {
ret.wait();
}
return 0;
}