C++C++ 11C++ 11
Lichermione1.共享智能指针
智能指针:模板类。
1.1初始化
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
| #include <iostream> #include <memory> using namespace std;
class test { public: test() { cout << "test()" << endl; }
test(int x) :_num(x) { cout << "test(int x) : " << x << endl; }
test(string str) { cout << "test(string str : " << str << endl; }
~test() { cout << "~test()" << endl; }
private: int _num; };
int main() {
shared_ptr<int> ptr1(new int{ 44 }); shared_ptr<int[]> ptr2(new int[5]{ 44 });
cout << "ptr1的引用计数:" << ptr1.use_count() << endl; cout << "ptr2的引用计数:" << ptr2.use_count() << endl;
shared_ptr<int> ptr3 = ptr1; shared_ptr<int[]> ptr4(ptr2); cout << "ptr1的引用计数:" << ptr1.use_count() << endl; cout << "ptr2的引用计数:" << ptr2.use_count() << endl; cout << "ptr3的引用计数:" << ptr3.use_count() << endl; cout << "ptr4的引用计数:" << ptr4.use_count() << endl;
shared_ptr<int> ptr5 = move(ptr3); shared_ptr<int[]> ptr6(move(ptr4)); cout << "ptr1的引用计数:" << ptr1.use_count() << endl; cout << "ptr2的引用计数:" << ptr2.use_count() << endl; cout << "ptr3的引用计数:" << ptr3.use_count() << endl; cout << "ptr4的引用计数:" << ptr4.use_count() << endl; cout << "ptr5的引用计数:" << ptr5.use_count() << endl; cout << "ptr6的引用计数:" << ptr6.use_count() << endl;
shared_ptr<int> ptr7 = make_shared<int>(55); shared_ptr<test> ptr8 = make_shared<test>(6); shared_ptr<test> ptr9 = make_shared<test>("cccccccccc"); shared_ptr<test> ptr10 = make_shared<test>(); cout << "ptr10的引用计数:" << ptr10.use_count() << endl;
ptr10.reset(); cout << "ptr10的引用计数:" << ptr10.use_count() << endl;
ptr10.reset(new test("licher")); cout << "ptr10的引用计数:" << ptr10.use_count() << endl; return 0; }
|
1.2使用
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
| #include <iostream> #include <memory> using namespace std;
class test { public: test() { cout << "test()" << endl; }
test(int x) :_num(x) { cout << "test(int x) : " << x << endl; }
test(string str) { cout << "test(string str : " << str << endl; }
void print() { cout << "hello test" << endl; }
~test() { cout << "~test()" << endl; }
private: int _num; };
int main() { shared_ptr<test> ptr1(new test(10)); shared_ptr<test> ptr2 = make_shared<test>("lichermionex");
test* p = ptr1.get(); p->print();
ptr1->print();
return 0; }
|
1.3 指定删除器
为什么需要删除器,因为数组类型无法全部进行析构。
构造对象的时候,需要一个匿名函数或者默认的函数。
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
| #include <iostream> #include <memory> using namespace std;
class test { public: test() { cout << "test()" << endl; }
test(int x) :_num(x) { cout << "test(int x) : " << x << endl; }
test(string str) { cout << "test(string str : " << str << endl; }
void print() { cout << "hello test" << endl; }
~test() { cout << "~test()" << endl; }
private: int _num; };
int main() {
shared_ptr<test> ppp(new test[5], [](test* t) { cout << "------------" << endl; delete[] t; });
shared_ptr<test> ppp2(new test[5], [](test* t) { cout << "------------" << endl; delete[] t; });
shared_ptr<int> p1(new int[10] {0}, default_delete<int[]>()); shared_ptr<test> p2(new test[10], default_delete<test[]>());
return 0; }
|
1.4 总结
1 2 3
| 1.智能指针:模板类,这样子就可以管理任意类型的指针指向的内存。 2.初始化,需要开辟堆内存。可以赋值或者拷贝。 3.c++11管理数组需要指定删除函数。
|
2.独享智能指针
2.1初始化
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
| #include <iostream> #include <memory> using namespace std;
int main() {
unique_ptr<int> ptr1(new int{ 33 });
unique_ptr<int> ptr2(move(ptr1)); unique_ptr<int> ptr3 = move(ptr2);
ptr3.reset(); ptr3.reset(new int{ 555 }); ptr3.reset(new int{ 444 });
int* p = ptr3.get(); cout << *p << endl; cout << *ptr3 << endl;
return 0; }
|
2.2指定删除器
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
| #include <iostream> #include <functional> #include <memory> using namespace std;
class test { public: test() { cout << "test()" << endl; }
test(int x) :_num(x) { cout << "test(int x) : " << x << endl; }
test(string str) { cout << "test(string str : " << str << endl; }
void print() { cout << "hello test" << endl; }
~test() { cout << "~test()" << endl; }
private: int _num; };
int main() { using ptrFunc = void(*)(test*); unique_ptr<test,ptrFunc> ptr(new test("cccc"), [](test* t) { cout << "-----1" << endl; delete t; });
unique_ptr<test, function<void(test*)>> ptr2(new test("cccc"), [=](test* t) { cout << "-----2" << endl; delete t; });
unique_ptr<test[]> ptr3(new test[3]);
shared_ptr<test[]> ptr3(new test[3]);
return 0; }
|
1.3 总结
1 2 3
| 1.同共享智能指针。 2.C++11就可以管理数组了的。 3.不支持拷贝赋值和拷贝构造。
|
3.弱引用智能指针
弱引用指针只是用来观测共享指针的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <memory> using namespace std;
int main() {
shared_ptr<int> sp(new int{ 55 });
weak_ptr<int> wp1; weak_ptr<int> wp2(wp1); weak_ptr<int> wp3(sp);
weak_ptr<int> wp4; wp4 = sp; weak_ptr<int> wp5; wp5 = wp3;
return 0; }
|
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
| #include <iostream> #include <memory> using namespace std;
class test { public: test() { cout << "test()" << endl; }
void print() { cout << "Hello world" << endl; }
~test() { cout << "~test()" << endl; } };
int main() {
shared_ptr<test> t1(new test);
weak_ptr<test> t2 = t1; weak_ptr<test> t3(t1);
if (auto p = t2.lock()) { cout << p.use_count() << endl; p->print(); } else { cout << "对象已经不存在了" << endl; }
cout << t1.use_count() << endl;
cout << t2.expired() << endl; cout << t3.expired() << endl;
return 0; }
|
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
| #include <iostream> #include <memory> using namespace std;
struct TA; struct TB;
struct TA { weak_ptr<TB> bptr; ~TA() { cout << "~TA" << endl; } };
struct TB { shared_ptr<TA> aptr; ~TB() { cout << "~TB" << endl; } };
int main() { shared_ptr<TA> ap(new TA); shared_ptr<TB> bp(new TB);
cout << "TA USE_COUNT : " << ap.use_count() << endl; cout << "TB USE_COUNT : " << bp.use_count() << endl;
ap->bptr = bp; bp->aptr = ap;
cout << "TA USE_COUNT : " << ap.use_count() << endl; cout << "TB USE_COUNT : " << bp.use_count() << endl;
return 0; }
|
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
| #include <iostream> #include <memory> using namespace std;
class test: public enable_shared_from_this<test> { public:
shared_ptr<test> getSharePtr() { return shared_from_this(); }
~test() { cout << "~test()" << endl; } };
int main() {
shared_ptr<test> sp1(new test); shared_ptr<test> sp2 = sp1->getSharePtr(); cout << sp1.use_count() << endl; cout << sp2.use_count() << endl;
return 0; }
|
4 POD类型
平凡类型:类的默认六大函数 + 没有虚函数 + 没有虚基类(虚继承的对象)。
1 2 3 4 5 6 7 8 9
| int main() { return 0; }
|
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
| #include <iostream> #include <type_traits> using namespace std;
class test { public: test() = default; ~test() = default;
test(const test&) = default; test(test&&) = default;
test& operator=(const test&) = default; test& operator=(test&&) = default; };
int main() { cout<< "test 平凡pod类型 " << is_trivial<test>::value <<endl; return 0; }
|
标准布局类型
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
| #include <iostream> using namespace std;
struct Base { static int a; }; struct Child : public Base { int b; };
struct Base1 { int a; }; struct Child2 : public Base { static int b; };
struct Child3 : public Base, public Base1 { static int d; }; struct Child4 : public Base1 { int d; };
struct Child4 : public Base1, public Child { static int num; };
int main() {
return 0; }
|
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
| ```
**模板函数的测试**
```c++ #include <iostream> #include <type_traits> using namespace std;
struct Base { static int a; }; struct Child : public Base { int b; }; // pod类型
struct Base1 { int a; }; struct Child2 : public Base { static int b; }; // pod类型
struct Child3 : public Base, public Base1 { static int d; }; // pod类型 struct Child4 : public Base1 { int d; }; // 不是pod类型
class test { // 六大函数都是默认的 test() = default; test(int x){} };
int main() { // 平凡类型 cout << "test是不是平凡的POD类型 : " << is_trivial<test>::value << endl;
// 标准布局 cout << "标准布局类型 : " << is_standard_layout<Base>::value << endl;
return 0; }
|
5 default 和 delete
default :只能是对象的六大函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> using namespace std;
class A { public: A() = default; ~A() = default;
A(const A&) = default; A(A&&) noexcept = default;
A& operator=(const A&) = default; A& operator=(A&&) noexcept = default; };
int main() { return 0; }
|
delete : 删除默认函数
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
| #include <iostream> using namespace std;
class A { public: A() = default; ~A() = default;
A(const A&) = delete; A(A&&) noexcept = delete;
A& operator=(const A&) = delete; A& operator=(A&&) noexcept = delete;
void print(int num) { cout << "num : " << num << endl; }
void print(char ch) = delete; };
int main() { A().print(22);
return 0; }
|
6 友元
c++11 声明类的时候,可以减少class关键字。
友元可以使用别名了的。
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
| #include <iostream> #include <string> using namespace std;
class Tom; using Honey = Tom;
class Jack { friend Tom; private: string name = "jack"; void print() { cout << "my name is " << name << endl; } };
class Lucy { friend Honey; private: string name = "lucy"; void print() { cout << "my name is " << name << endl; } };
class Tom { public: void print() { cout << j.name << " : " << l.name << endl; j.print(); l.print(); }
private: Jack j; Lucy l; };
int main() { Tom t; t.print();
return 0; }
|
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
| #include <iostream> using namespace std;
template<class T> class Rectangle { friend T; public: Rectangle(int width, int height) :_width(width) ,_height(height) { }
private: int _width; int _height; };
template<class T> class Circle { friend T; public: Circle(int radius) :_radius(radius) { }
private: int _radius; };
class verify { public: verify(int w, int h, Rectangle<verify>& r) { if (r._width > w && r._height > h) { cout << "矩形的宽度和高度符合要求" << endl; } else { cout << "矩形的宽度和高度不不符合要求" << endl; } }
verify(int r, Circle<verify>& c) { if (c._radius < r) { cout << "圆的半径符合要求" << endl; } else { cout << "圆的半径不符合要求" << endl; } } };
int main() { Rectangle<verify> rect(100, 100); Circle<verify> circle(90);
verify(100, 200, rect); verify(50, circle);
return 0; }
|
7强类型枚举
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
| #include <iostream> using namespace std;
enum test{ Red, Green, Blue }; enum Color1{ Red2, Green2, Blue2 }; enum class Color2 { Red, Green, Blue }; enum struct Color3 { Red, Green, Blue };
enum struct Color4 : char { Red, Green, Blue };
int main() {
cout << "Color2::Red2 : " << (int)Color2::Red << endl; cout << "Color2 size :" << sizeof(Color2::Red) << endl; cout << "Color4 size :" << sizeof(Color4::Red) << endl;
return 0; }
|
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
| #include <iostream> #include <string> using namespace std;
class Base { public: Base(){} };
union test { static int num; int num2; static void print() { num = 999; }
};
int test::num = 0;
int main() {
test::print();
test t1;
t1.num2 = 222; cout << "static int num : " << t1.num << endl; cout << "int num2 : " << t1.num2 << endl;
test t2; t2.num2 = 444; cout << "static int num : " << t2.num << endl; cout << "int num2 : " << t2.num2 << endl;
return 0; }
|
定位放置new 解决非 POD类型
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
| #include <iostream> #include <string> using namespace std;
class test { public: test(){} void settest(string s) { _name = s; }
private: string _name; };
union Student { Student() { new (&_name)string; } ~Student(){}
int _id; string _name; test t; };
int main() {
Student s; s._name = "lic"; s.t.settest("lic2"); cout << "s._name:" << s._name << endl;
return 0; }
|
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
| #include <iostream> #include <string> using namespace std;
class Foreigner { public: Foreigner(string a, string b) :addr(a) ,phone(b) { } string addr; string phone; };
class person { public: enum class category : char {student, local, fore};
person(int num) :number(num) ,c(category::student) { }
person(string str) :idnum(str) ,c(category::local) { }
person(string a, string b) :fore(a,b) ,c(category::fore) { }
void print() { switch (c) { case category::student:
break; case category::local:
break; case category::fore:
break; } }
~person() { }
private: union { int number; string idnum; Foreigner fore; }; category c; };
int main() { return 0; }
|
8 处理时间的库
8.1 duration
时间库 chrono: 时间间隔, 时钟, 时间点。
duration的基本定义
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
| #include <iostream> #include <chrono> using namespace std; using namespace chrono;
int main() {
duration<int, ratio<3600, 1>> hour(1); hours h(4);
duration<int, ratio<60, 1>> min(1); minutes m(1);
duration<int, ratio<1, 1>> minn(1); seconds s(1);
duration<int, ratio<1,1000>> min2(1); milliseconds msec(1);
duration<int, ratio<1,1000000>> min3(1); microseconds mirco(1);
duration<int, ratio<1,1000000000>> min4(1); nanoseconds nana(1);
duration<double> sec1(2.5);
cout << "时间周期:" << sec1.count() << endl; cout << "时间周期:" << h.count() << endl;
return 0; }
|
duration的重载方法。
分组最大公约数,分母最小的公倍数。
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
| #include <iostream> #include <chrono> using namespace std; using namespace chrono;
int main() {
minutes m1(9); minutes m2(8); m1++; m2--; minutes m3 = m1 - m2;
duration<int, ratio<60, 1>> t1(60); duration<int, ratio<1, 1>> t2(60); duration<int, ratio<1, 1>> t3 = t1 - t2;
duration<double, ratio<9, 7>> d1(3); duration<double, ratio<6, 5>> d2(1); duration<double, ratio<3, 35>> d3 = d1 - d2;
cout << "时钟周期:" << d3.count() << endl;
return 0; }
|
8.2 system_clock
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
| #include <iostream> #include <chrono> using namespace std; using namespace chrono;
void fun() { system_clock::time_point epoch;
hours h(10 * 24); system_clock::time_point epoch1 = epoch + h; system_clock::time_point epoch2(epoch + h);
system_clock::time_point nowtime = system_clock::now();
time_t allsec = system_clock::to_time_t(nowtime);
cout << "当前时间:" << ctime(&allsec);
system_clock::time_point tp = system_clock::from_time_t(allsec); }
int main() {
fun(); return 0; }
|
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
| #include <iostream> #include <chrono> using namespace std; using namespace chrono;
void fun() { auto p1 = steady_clock::now(); for (int i = 0; i < 1000; ++i) {
} auto p2 = steady_clock::now();
auto d1 = p2 - p1;
cout << "count:" << d1.count() << endl; }
int main() { fun();
return 0; }
|
8.3转换函数
9 C11线程
9.1 this_thread
获取线程id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <iostream> #include <thread> using namespace std;
void func() { cout << "子线程id:" << this_thread::get_id() << endl; }
int main() { cout << "主线程id:" << this_thread::get_id() << endl;
thread t(func);
t.join();
return 0; }
|
阻塞线程
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
| #include <iostream> #include <thread> #include <chrono> using namespace std;
void func() { for (int i = 0; i < 10; ++i) { this_thread::sleep_for(chrono::seconds(1)); cout << "i : " << i << endl; } }
int main() { cout << "我是主线,id:" << this_thread::get_id() << endl;
thread t(func); t.join();
return 0; }
|
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
| #include <iostream> #include <thread> #include <chrono> using namespace std;
void func() { for (int i = 0; i < 10; ++i) { auto now = chrono::system_clock::now(); chrono::seconds sec(1); this_thread::sleep_until(now + sec);
this_thread::yield();
cout << "i : " << i << endl; } }
int main() { cout << "我是主线,id:" << this_thread::get_id() << endl;
thread t(func); t.join();
return 0; }
|
9.2 thread
创建线程对象
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
| #include <iostream> #include <thread> using namespace std;
void func1() { cout << "我是子线程,叫做lic1 ,id:" << this_thread::get_id() << endl; }
void func2(string name, int age) { cout << "name : " << name << " : " << "age : " << age << "线程i:" << this_thread::get_id() << endl; }
int main() {
thread t1; thread t2(func1); thread t3(func2, "lic", 22); thread t4([](int id) { cout << "id : " << id << "线程i:" << this_thread::get_id() << endl; }, 1001);
thread&& t5 = move(t4);
cout << "t2 id :" << t2.get_id() << endl; cout << "t3 id :" << t3.get_id() << endl; cout << "t4 id :" << t4.get_id() << endl; cout << "t5 id :" << t5.get_id() << endl;
t2.join(); t3.join(); t5.join();
return 0; }
|
子线程关系判断
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
| #include <iostream> #include <thread> using namespace std;
void func1() { cout << "我是子线程,叫做lic1 ,id:" << this_thread::get_id() << endl; }
void func2(string name, int age) { cout << "name : " << name << " : " << "age : " << age << "线程i:" << this_thread::get_id() << endl; }
int main() {
thread t1; thread t2(func1); thread t3(func2, "lic", 22); thread t4([](int id) { cout << "id : " << id << "线程i:" << this_thread::get_id() << endl; }, 1001);
cout << "t1:" << t1.joinable() << endl; cout << "t2:" << t2.joinable() << endl; cout << "t3:" << t3.joinable() << endl; cout << "t4:" << t4.joinable() << endl;
t2.join(); t3.join(); t4.join();
cout << "t1:" << t1.joinable() << endl; cout << "t2:" << t2.joinable() << endl; cout << "t3:" << t3.joinable() << endl; cout << "t4:" << t4.joinable() << endl;
return 0; }
|
静态方法
1 2 3 4 5 6 7 8 9 10
| #include <iostream> #include <thread> using namespace std;
int main() { cout << thread::hardware_concurrency() << endl;
return 0; }
|
对象的成员函数
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
| #include <iostream> #include <functional> #include <thread> #include <string> using namespace std;
class test { public: void showMsg(string name, int id) { cout << "name:" << name << ":" << "id:" << id << endl; }
static void messgae() { cout << "至德者沉默,闻道者言说" << endl; } };
int main() {
thread t1(&test::messgae);
test t; thread t2(&test::showMsg, &t, "lic", 22); thread t3(&test::showMsg, t, "lic", 23);
thread t4(bind(&test::showMsg, &t, "lic", 24)); thread t5(bind(&test::showMsg, t, "lic", 25));
t1.join(); t2.join(); t3.join(); t4.join(); t5.join();
return 0; }
|
call_once函数
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
| #include <iostream> #include <functional> #include <thread> #include <string> #include <mutex> using namespace std;
once_flag flag;
void do_once(int a, int b) { cout << "a:" << a << endl; cout << "b:" << b << endl; }
void do_something(int id, string name) { cout << "id:" << id << endl; cout << "name:" << name << endl; call_once(flag, do_once, 1, 3); }
int main() { thread t1(do_something, 1, "lic1"); thread t2(do_something, 3, "lic2"); thread t3(do_something, 2, "lic3");
t1.join(); t2.join(); t3.join();
return 0; }
|
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
| #include <iostream> #include <functional> #include <thread> #include <string> #include <mutex> using namespace std;
once_flag flag;
class Base { public: Base(const Base& obj) = delete; Base& operator=(const Base& obj) = delete;
static Base* getInstanc() { call_once(flag, [&]() { obj = new Base; cout << "创建实例对象" << endl; });
return obj; }
void set(string name) { _name = name; }
string get() { return _name; }
private: Base(){} static Base* obj; string _name; };
Base* Base::obj = nullptr;
void func(string name) { Base::getInstanc()->set(name); cout << "name:" << Base::getInstanc()->get() << endl; }
int main() { thread t1(func, "lic1"); thread t2(func, "lic2"); thread t3(func, "lic3"); thread t4(func, "lic4");
t1.join(); t2.join(); t3.join(); t4.join();
return 0; }
|
9.3 线程互斥
独占锁
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
| #include <iostream> #include <thread> #include <mutex> #include <chrono> using namespace std;
class Base { public: void increment(int count) { for (int i = 0; i < count; ++i) { _mutex.lock();
_num++; cout << "increment _num:" << _num << endl;
_mutex.unlock();
this_thread::sleep_for(chrono::milliseconds(500)); } }
void decrement(int count) { for (int i = 0; i < count; ++i) { _mutex.lock();
_num--; cout << "decrement _num:" << _num << endl;
_mutex.unlock();
this_thread::yield(); } }
private: int _num = 44; mutex _mutex; };
int main() { Base b; thread t1(&Base::increment, &b, 100); thread t2(&Base::decrement, &b, 100);
t1.join(); t2.join();
return 0; }
|
守护锁
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
| #include <iostream> #include <thread> #include <mutex> #include <chrono> using namespace std;
class Base { public: void increment(int count) { for (int i = 0; i < count; ++i) { { lock_guard<mutex> gurad(_mutex);
_num++; cout << "increment _num:" << _num << endl; }
this_thread::sleep_for(chrono::milliseconds(500)); } }
void decrement(int count) { for (int i = 0; i < count; ++i) { { lock_guard<mutex> gurad(_mutex);
_num--; cout << "decrement _num:" << _num << endl; }
this_thread::yield(); } }
private: int _num = 44; mutex _mutex;
};
int main() { Base b; thread t1(&Base::increment, &b, 10); thread t2(&Base::decrement, &b, 10);
t1.join(); t2.join();
return 0; }
|
递归锁
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
| #include <iostream> #include <thread> #include <mutex> #include <chrono> using namespace std;
class Base { public: void increment(int count) { for (int i = 0; i < count; ++i) { _mutex.lock();
_num++; cout << "increment _num:" << _num << endl;
_mutex.unlock();
this_thread::sleep_for(chrono::milliseconds(500)); } }
void decrement(int count) { for (int i = 0; i < count; ++i) { { lock_guard<recursive_mutex> gurad(_mutex);
increment(2);
_num--; cout << "decrement _num:" << _num << endl; }
this_thread::yield(); } }
private: int _num = 44; recursive_mutex _mutex;
};
int main() { Base b; thread t1(&Base::increment, &b, 10); thread t2(&Base::decrement, &b, 10);
t1.join(); t2.join();
return 0; }
|
超时互斥锁
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
| #include <iostream> #include <thread> #include <mutex> #include <chrono> using namespace std;
class Base { public: void increment(int count) { for (int i = 0; i < count; ++i) {
_mutex.lock();
_num++; cout << "increment _num:" << _num << endl;
_mutex.unlock();
this_thread::sleep_for(chrono::milliseconds(500)); } }
void decrement(int count) { for (int i = 0; i < count; ++i) { { lock_guard<recursive_mutex> gurad(_mutex);
increment(2);
_num--; cout << "decrement _num:" << _num << endl; }
this_thread::yield(); } }
void work() { while (true) { if (_tmutex.try_lock_for(chrono::milliseconds(100))) { count++; this_thread::sleep_for(chrono::milliseconds(500)); cout << "线程抢到互斥锁 线程id:" << this_thread::get_id() << endl;
_tmutex.unlock();
break; } else { cout << "线程没有抢到互斥锁 线程id:" << this_thread::get_id() << endl; this_thread::sleep_for(chrono::milliseconds(500)); } } }
private: int _num = 44; int count = 0; recursive_mutex _mutex; timed_mutex _tmutex; };
int main() { Base b; thread t1(&Base::work, &b); thread t2(&Base::work, &b);
t1.join(); t2.join();
return 0; }
|
9.4线程同步
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
| #include <iostream> #include <thread> #include <mutex> #include <condition_variable> #include <chrono> #include <queue> using namespace std;
class task { public: void put(int x) { unique_lock<mutex> locker(_mutex);
while(taskQueue.size() == _maxSize) { notfull.wait(locker); }
taskQueue.push(x); cout << "线程id" << this_thread::get_id() << " 添加任务:" << x << endl;
notempty.notify_one(); }
void take() { unique_lock<mutex> locker(_mutex);
while (taskQueue.empty()) { notempty.wait(locker); }
int num = taskQueue.front(); taskQueue.pop(); cout << "线程id" << this_thread::get_id() << " 消费任务:" << num << endl;
notfull.notify_one(); }
bool isFull() { lock_guard<mutex> locker(_mutex); if (taskQueue.size() == _maxSize) { return true; }
return false; }
bool isEmpty() { lock_guard<mutex> locker(_mutex); if (taskQueue.size() == 0) { return true; }
return false; }
int taskSize() { lock_guard<mutex> locker(_mutex); return taskQueue.size(); }
private: int _maxSize = 100; queue<int> taskQueue; mutex _mutex; condition_variable notfull; condition_variable notempty; };
int main() {
thread t1[5]; thread t2[5]; task taskqueue;
for (int i = 0; i < 5; ++i) { t1[i] = thread(&task::put, &taskqueue, 100 + i); t2[i] = thread(&task::take, &taskqueue); }
for (int i = 0; i < 5; ++i) { t1[i].join(); t2[i].join(); }
return 0; }
|
wait方法带回调函数。
10 原子对象
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
| #include <iostream> #include <atomic> using namespace std;
struct base { int age; char ch; };
int main() {
atomic<int> t1; atomic<int> t2(22); atomic<char> t3('a'); atomic_char t4('b');
atomic<int> t5(55); t5 = 44; t5.store(33); int c = t5.exchange(22);
cout << "t5:" << t5 << endl; cout << "c:" << c << endl; cout << "t5.loacd:" << t5.load() << endl;
base b{ 1, 'c' }; atomic<base*> tt(&b);
base* temp = tt.load(); cout << "base 1 :" << temp->age << endl; cout << "base 2 :" << temp->ch << endl;
return 0; }
|
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
| #include <iostream> #include <atomic> #include <thread> #include <mutex> using namespace std;
class test { public: void increment() { for (int i = 0; i < 10000; ++i) { ++number; cout << "increment number:" << number << endl; } }
void decrement() { for (int i = 0; i < 10000; ++i) { --number; cout << "decrement number:" << number << endl; } }
private: atomic_int number = 100; };
int main() { test t; thread t1(&test::increment, &t); thread t2(&test::decrement, &t);
t1.join(); t2.join();
return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <iostream> #include <atomic> #include <thread> #include <mutex> using namespace std;
int main() {
return 0; }
|
11 线程异步


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
| #include <iostream> #include <future> #include <thread> #include <chrono> using namespace std;
int add(int x, int y) { cout << "子线程" << this_thread::get_id() << endl; this_thread::sleep_for(chrono::seconds(3)); return x + y; }
int main() {
future<int> fur = async(launch::async, add, 33, 44); cout << "主线程" << this_thread::get_id() << endl; cout << "我是主线程" << endl;
int result = fur.get();
cout << "result:" << result << endl;
return 0; }
|
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
| #include <iostream> #include <future> #include <thread> #include <chrono> using namespace std;
int add(int x, int y) { cout << "子线程" << this_thread::get_id() << endl; this_thread::sleep_for(chrono::seconds(3)); return x + y; }
int main() {
future<int> fur = async(launch::async, add, 33, 44); cout << "主线程" << this_thread::get_id() << endl; cout << "我是主线程" << endl;
fur.wait(); int result = fur.get();
cout << "result : " << result << endl;
return 0; }
|
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
| #include <iostream> #include <future> #include <thread> #include <chrono> using namespace std;
int add(int x, int y) { cout << "子线程" << this_thread::get_id() << endl; this_thread::sleep_for(chrono::seconds(3)); return x + y; }
int main() {
future<int> fur = async(launch::async, add, 33, 44); cout << "主线程" << this_thread::get_id() << endl; cout << "我是主线程" << endl;
auto status = fur.wait_for(chrono::seconds(10)); if (status == future_status::ready) { cout << fur.get() << endl; } else if(status == future_status::timeout) { cout << "任务还没有执行完" << endl; } else if(status == future_status::deferred) { cout << "任务尚未执行,属于延迟执行" << endl; }
return 0; }
|
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
| #include <iostream> #include <thread> #include <future> using namespace std;
void worker(promise<int> p) { int result = 10 + 20; p.set_value(result); }
int main() { promise<int> p;
future<int> fut = p.get_future();
thread t(worker, move(p));
cout << fut.get() << endl;
t.join(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <future> #include <thread> using namespace std;
int add(int a, int b) { return a + b; }
int main() { packaged_task<int(int, int)> task(add);
future<int> fut = task.get_future();
thread t(move(task), 10, 20);
cout << fut.get() << endl;
t.join(); }
|
12 万能引用
万能引用
- 模板类型推导
- 引用折叠(Reference Collapsing)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> using namespace std;
template<class T> void func(T&& value) { cout << "value:" << value << endl; }
int main() { func<int>(10); int a = 22; func<int>(std::move(a)); int& b = a; b = 4; func<int>(std::move(b));
return 0; }
|
完美转发
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
| #include <iostream> using namespace std;
void print(int& value) { cout << "int&:" << value << endl; }
void print(int&& value) { cout << "int&&:" << value << endl; }
template<class T> void func(T&& value) { print(forward<T>(value)); }
int main() { int a = 10; func(a); func(22);
return 0; }
|
无论变量声明时的类型是左值引用还是右值引用,只要它是有名字的变量,作为表达式使用时就是左值。


Lichermione
天行健,君子以自强不息;
地势坤,君子以厚德载物。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LichermioneX 的博客!