Skip to content

Commit

Permalink
fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixFu520 committed Oct 12, 2021
1 parent 4c13c03 commit 6a45fa1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 39 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# 🍭理论篇

- [200+本计算机书籍](https://github.com/imarvinle/awesome-cs-books)
-

## 1⃣️ 数学

## 2⃣️ 语言
Expand All @@ -22,6 +25,9 @@
- 🐾 [侯杰C++学习教程](https://github.com/TD-4/Bilibili-plus)
- 🐾 [C++设计模式-代码1](https://github.com/TD-4/CPP-Design-Patterns)[视频](https://www.bilibili.com/video/BV1Eb4y1m7Uj?from=search&seid=17226351057292842857&spm_id_from=333.337.0.0)| [代码2](https://github.com/TD-4/Cpp-Design-Patterns-1)
- 🐾 [C++并发与多线程--笔记](theory/cpp/multi_thread.md)[视频 王建伟](https://www.bilibili.com/video/BV1Yb411L7ak?p=2&spm_id_from=pageDriver)|
- [1、线程C语言-苏丙榅](https://subingwen.cn/linux/thread/)|[C++](https://subingwen.cn/cpp/thread/)
- [2、文件描述符](https://subingwen.cn/linux/file-descriptor/)
- [3、线程池C语言](https://subingwen.cn/linux/threadpool/)|[C++](https://subingwen.cn/linux/threadpool-cpp/) | [自己](https://github.com/TD-4/thread-pool)

#### 🍃 函数

Expand All @@ -42,6 +48,7 @@
- [noexcept 运算符](https://veitchkyrie.github.io/2020/02/24/C++-noexcept-%E8%BF%90%E7%AE%97%E7%AC%A6/)
- [C++ 中的 Lambda 表达式](https://docs.microsoft.com/zh-cn/cpp/cpp/lambda-expressions-in-cpp?view=msvc-160)
- [C++11新特性之十一:emplace](https://blog.csdn.net/f110300641/article/details/83416411)
- [C++ explicit](https://www.cnblogs.com/this-543273659/archive/2011/08/02/2124596.html)

#### 🍃 C++工具

Expand Down
68 changes: 29 additions & 39 deletions theory/cpp/multi_thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

## 1. 并发基本概念及实现,进程、线程基本概念

**一 并发基本概念及实现,进程、线程基本概念**

![在这里插入图片描述](imgs/fcbdaeb87cd5a8987afd06a2c650e7b9.png)


Expand Down Expand Up @@ -97,9 +95,7 @@ b)在单独的进程中,写代码创建除了主线程之外的其他线程

- 从C++11新标准,C++语言本身增加对多线程的支持,意味着可移植性(跨平台),这大大减少开发人员的工作量

# 2. 线程启动、结束,创建线程多法、join,detach

**第二节 线程启动、结束,创建线程多法、join,detach**
## 2. 线程启动、结束,创建线程多法、join,detach

![在这里插入图片描述](imgs/asdfasdfasdfasdf)

Expand Down Expand Up @@ -242,9 +238,7 @@ public:
```

# 3. 线程传参详解,detach()大坑,成员函数做线程函数

**第三节 线程传参详解,detach()大坑,成员函数做线程函数**
## 3. 线程传参详解,detach()大坑,成员函数做线程函数

![在这里插入图片描述](imgs/hgsf.png)

Expand Down Expand Up @@ -437,8 +431,6 @@ int main()

## 4. 创建多个线程、数据共享问题分析、案例代码

**第四节 创建多个线程、数据共享问题分析、案例代码**

![在这里插入图片描述](imgs/hgf)

### **一、创建和等待多个线程**
Expand Down Expand Up @@ -477,9 +469,7 @@ void TextThread()
- 最简单的防止崩溃方法:读的时候不能写,写的时候不能读。
- 写的动作分10小步,由于任务切换,导致各种诡异的事情发生(最可能的还是崩溃)

# 5. 互斥量概念、用法、死锁演示及解决详解

## 第五节 互斥量概念、用法、死锁演示及解决详解
## 5. 互斥量概念、用法、死锁演示及解决详解

![在这里插入图片描述](imgs/fff.png)

Expand All @@ -493,13 +483,13 @@ void TextThread()

包含#include <mutex>头文件

#### 2.1 lock(),unlock()
##### 2.1 lock(),unlock()

步骤:1.lock(),2.操作共享数据,3.unlock()。

lock()和unlock()要成对使用

#### 2.2 lock_guard类模板
##### 2.2 lock_guard类模板

lock_guard<mutex> sbguard(myMutex);取代lock()和unlock()

Expand All @@ -509,7 +499,7 @@ lock_guard构造函数执行了mutex::lock();

### 三、死锁

#### 3.1 死锁演示
##### 3.1 死锁演示

死锁至少有两个互斥量mutex1,mutex2。

Expand All @@ -519,18 +509,18 @@ b.线程B执行,这个线程先锁mutex2,因为mutex2没有被锁,即mutex

c.此时,死锁产生了,A锁着mutex1,需要锁mutex2,B锁着mutex2,需要锁mutex1,两个线程没办法继续运行下去。。。

#### 3.2 死锁的一般解决方案:
##### 3.2 死锁的一般解决方案:

只要保证多个互斥量上锁的顺序一样就不会造成死锁。

#### 3.3 std::lock()函数模板
##### 3.3 std::lock()函数模板

std::lock(mutex1,mutex2……); 一次锁定多个互斥量(一般这种情况很少),用于处理多个互斥量。
如果互斥量中一个没锁住,它就等着,等所有互斥量都锁住,才能继续执行。如果有一个没锁住,就会把已经锁住的释放掉(要么互斥量都锁住,要么都没锁住,防止死锁)

#### 3.4 std::lock_guard的std::adopt_lock参数
##### 3.4 std::lock_guard的std::adopt_lock参数

std::lock_guardstd::mutex my_guard(my_mutex,std::adopt_lock);
`std::lock_guard<std::mutex> my_guard(my_mutex,std::adopt_lock);`
加入adopt_lock后,在调用lock_guard的构造函数时,不再进行lock();
adopt_guard为结构体对象,起一个标记作用,表示这个互斥量已经lock(),不需要在lock()。

Expand Down Expand Up @@ -609,21 +599,19 @@ int main()
```

# 6. unique_lock(类模板)详解

**第六节 unique_lock(类模板)详解**
## 6. unique_lock(类模板)详解

![在这里插入图片描述](imgs/fd.png)

### 1.unique_lock取代lock_guard
#### 1.unique_lock取代lock_guard

unique_lock比lock_guard灵活很多(多出来很多用法),效率差一点。

unique_lock<mutex> myUniLock(myMutex);

### 2.unique_lock的第二个参数
#### 2.unique_lock的第二个参数

#### 2.1 std::adopt_lock:
##### 2.1 std::adopt_lock:

表示这个互斥量已经被lock(),即不需要在构造函数中lock这个互斥量了。

Expand All @@ -635,7 +623,7 @@ lock_guard中也可以用这个参数

`std::lock_guard<std::mutex> sbguard1(my_mutex1, std::adopt_lock)`

#### 2.2 std::try_to_lock:
##### 2.2 std::try_to_lock:

尝试用mutex的lock()去锁定这个mutex,但如果没有锁定成功,会立即返回,不会阻塞在那里;
使用try_to_lock的原因是防止其他的线程锁定mutex太长时间,导致本线程一直阻塞在lock这个地方
Expand All @@ -655,9 +643,7 @@ else{
}
```



#### 2.3 std::defer_lock:
##### 2.3 std::defer_lock:

如果没有第二个参数就对mutex进行加锁,加上defer_lock是始化了一个没有加锁的mutex
不给它加锁的目的是以后可以调用unique_lock的一些方法
Expand All @@ -666,9 +652,9 @@ else{



### 3.unique_lock的成员函数(前三个与std::defer_lock联合使用)
#### 3.unique_lock的成员函数(前三个与std::defer_lock联合使用)

#### 3.1 lock():加锁。
##### 3.1 lock():加锁。

```
unique_lock<mutex> myUniLock(myMutex, defer_lock);
Expand All @@ -678,7 +664,7 @@ myUniLock.lock();

不用自己unlock();

#### *3.2 unlock():解锁。*
##### *3.2 unlock():解锁。*

```
unique_lock<mutex> myUniLock(myMutex, defer_lock);
Expand All @@ -693,7 +679,7 @@ myUniLock.lock();

因为一些非共享代码要处理,可以暂时先unlock(),用其他线程把它们处理了,处理完后再lock()。

#### 3.3 try_lock():尝试给互斥量加锁
##### 3.3 try_lock():尝试给互斥量加锁

如果拿不到锁,返回false,否则返回true。

Expand All @@ -707,7 +693,7 @@ if(sbguard1.try_lock()==true){



#### 3.4 release():
##### 3.4 release():

`unique_lock<mutex> myUniLock(myMutex);`

Expand All @@ -724,16 +710,16 @@ b.锁住的代码多,叫做粒度粗,执行效率低;



### 4.unique_lock所有权的传递
#### 4.unique_lock所有权的传递

unique_lock<mutex> myUniLock(myMutex);把myMutex和myUniLock绑定在了一起,也就是myUniLock拥有myMutex的所有权

1. #### 使用move转移
1. ##### 使用move转移

myUniLock拥有myMutex的所有权,myUniLock可以把自己对myMutex的所有权转移,但是不能复制。
unique_lock<mutex> myUniLock2(std::move(myUniLock));
现在myUniLock2拥有myMutex的所有权。
2. #### 在函数中return一个临时变量,即可以实现转移
2. ##### 在函数中return一个临时变量,即可以实现转移

```
unique_lock<mutex> aFunction()
Expand All @@ -750,7 +736,7 @@ unique_lock<mutex> myUniLock2(std::move(myUniLock));



# 7. 单例设计模式共享数据分析、解决,call_once
## 7. 单例设计模式共享数据分析、解决,call_once

### 1.设计模式

Expand Down Expand Up @@ -1932,3 +1918,7 @@ a、采用某些计数开发程序提供的建议,遵照建议和指示来确
b、创建多线程完成业务;考虑可能被阻塞的线程数量,创建多余最大被阻塞线程数量的线程,如100个线程被阻塞再充值业务,开110个线程就是很合适的

c、线程创建数量尽量不要超过500个,尽量控制在200个之内;


### 四、C++11多线程总结

0 comments on commit 6a45fa1

Please sign in to comment.