/
9.6互斥锁和锁安全的共享数据.cpp
92 lines (85 loc) · 2.5 KB
/
9.6互斥锁和锁安全的共享数据.cpp
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
#include"print.h"
#include<mutex>
#include<thread>
#include<list>
#include<optional>
#include<future>
std::mutex animal_mutex;
class Animal {
using friend_t = std::list<Animal>;
std::string_view s_name{ "unk" };
friend_t l_friends{};
public:
Animal() = delete;
Animal(const std::string_view n) :s_name{n}{}
bool operator==(const Animal& o)const {
return s_name.data() == o.s_name.data();
}
bool is_friend(const Animal& o)const {
for (const auto& a : l_friends) {
if (a == o)return true;
}
return false;
}
std::optional<friend_t::iterator>find_friend(const Animal& o)noexcept {
for (auto it{ l_friends.begin() }; it != l_friends.end(); ++it) {
if (*it == o)return it;
}
return {};
}
void print()const noexcept {
std::lock_guard l{ animal_mutex };
auto n_animals{ l_friends.size() };
::print("Animal: {}, friends: ", s_name);
if (!n_animals)::print("none");
else {
for (auto n : l_friends) {
std::cout << n.s_name;
if (--n_animals)std::cout << ", ";
}
}
endl(std::cout);
}
bool add_friend(Animal& o)noexcept {
::print("add_friend {} -> {}\n", s_name, o.s_name);
if (*this == o)return false;
std::lock_guard l(animal_mutex);
if (!is_friend(o))l_friends.emplace_back(o);//无重复则插入
if (!o.is_friend(*this))o.l_friends.emplace_back(*this);
return true;
}
bool delete_friend(Animal& o)noexcept {
::print("delete_friend {} -> {}\n", s_name, o.s_name);
if (*this == o)return false;
std::lock_guard l{ animal_mutex };
if (auto it = find_friend(o))l_friends.erase(it.value());
if (auto it = o.find_friend(*this))o.l_friends.erase(it.value());
return true;
}
};
int main() {
auto cat1 = std::make_unique<Animal>("Felix");
auto tiger1 = std::make_unique<Animal>("Hobbes");
auto dog1 = std::make_unique<Animal>("Astro");
auto rabbit1 = std::make_unique<Animal>("Bugs");
auto a1 = std::async([&] {cat1->add_friend(*tiger1); });
auto a2 = std::async([&] {tiger1->add_friend(*rabbit1); });
auto a3 = std::async([&] {dog1->add_friend(*dog1); });
auto a4 = std::async([&] {rabbit1->add_friend(*cat1); });
a1.wait();
a2.wait();
a3.wait();
a4.wait();
auto p1 = std::async([&] {cat1->print(); });
auto p2 = std::async([&] {tiger1->print(); });
auto p3 = std::async([&] {dog1->print(); });
auto p4 = std::async([&] {rabbit1->print(); });
p1.wait();
p2.wait();
p3.wait();
p4.wait();
auto a5 = std::async([&] {cat1->delete_friend(*rabbit1); });
a5.wait();
auto p5 = std::async([&] {cat1->print(); });
auto p6 = std::async([&] {rabbit1->print(); });
}