天行健 发表于 2025-3-5 21:59:31

C++基础知识10.栈和队列、互斥锁

### 栈和队列

创建方法与前面的容器一样。

栈常用方法


| 函数         | 说明                           |
| -------------- | ---------------------------------- |
| top()      | 返回栈顶元素引用               |
| push(val)    | 将 val 入栈                      |
| void pop()   | 元素出站                         |
| swap(s1, s2) | 交换两个 stack 中的元素(C++11) |

队列常用方法


| 函数    | 说明                            |
| --------- | --------------------------------- |
| front() | 返回 queue 中第一个放入的元素   |
| back()| 返回 queue 中最后一个插入的元素 |

优先队列的接口和普通的队列一样,不过可以多传入一个比较器。

## 多线程

C++11 标准提供了 thread 类模板用于创建线程,该类模板定义在 thread 标准库中,因此在创建线程时,需要包含 thread 头文件。thread 类模板定义了一个无参构造函数和一个变参构造函数,因此在创建线程对象时,可以为线程传入参数,也可以不传入参数。需要注意的是,thread 类模板不提供拷贝构造函数、赋值运算符重载等函数,因此线程对象之间不可以进行拷贝、赋值等操作。

### 创建线程

注意:pthread 不是 Linux 下默认的库,在链接的时候无法找到 pthread 库函数的入口地址,在编译的时候需要加上参数 `-lpthread`,或者修改 VSCode 的配置参数。

```json
{
    "tasks": [
      {
            "type": "cppbuild",
            "label": "C/C++: g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
                "-lpthread"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
      }
    ],
    "version": "2.0.0"
}
```

> join 方法

```cpp
#include <iostream>
#include <thread>
using namespace std;
// g++ createThread.cpp -o a -std=c++11 -lpthread
void func(){
    int count = 100;
    for (size_t i = 0; i < count; i++){
      cout << "子线程" + i << endl;
    }
}

int main(){
    cout << "main 线程" << endl;
    thread t(func);
    t.join();
    cout << "main 线程继续" << endl;
    return 0;
}
```

> detach 方法

主线程和当前线程并发执行 ≈ Java Thread 的 start 方法。

```cpp
#include <iostream>
#include <thread>
using namespace std;

void func(){
    int count = 100;
    for (size_t i = 0; i < count; i++){
      cout << "子线程" + i << endl;
    }
}

int main(){
    cout << "main 线程" << endl;
    thread t(func);
    t.detach(); // 主线程和当前线程并发执行。
    int count = 100;
    for (size_t i = 0; i < count; i++){
      cout << "main 线程继续" << endl;
    }
    return 0;
}
```

### 互斥锁

对共享变量加锁解锁。C++11 标准提供了互斥锁 mutex,用于为共享资源加锁,让多个线程互斥访问共享资源。

mutex 是一个类模板,定义在 mutex 标准库中,使用时要包含 mutex 头文件。mutex 类模板定义了三个常用的成员函数:lock() 函数、unlock() 函数和 try_lock() 函数,用于实现上锁、解锁功能。


| 函数   | 说明                           |
| ---------- | ---------------------------------- |
| lock   | 加锁,拿不到锁就阻塞             |
| unlock   | 释放锁                           |
| try_lock | 尝试获取锁,拿不到锁就返回 false |

```cpp
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;

void testLock(){
    mutex locks;
    // 不可重入锁
    locks.lock();
    locks.lock();
    cout << "拿到锁" << endl;
    locks.unlock();
    cout << "释放锁" << endl;
}

int main(){
    thread t(testLock);
    t.join();
    cout << "main" << endl;
}
```

### this_thread命名空间


| 函数          | 说明                                                                                                                        |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| get_id()      | 获取当前线程 id                                                                                                               |
| yeild()       | 放弃当前线程的执行权。操作系统会调度其他线程执行未用完的时间片。<br>当时间片用完之后,当前线程再与其他线程一起竞争 CPU 资源。 |
| sleep_until() | 让当前线程休眠到某个时间点                                                                                                    |
| sleep_for()   | 让当前线程休眠一段时间                                                                                                      |

AO1199 发表于 2025-3-6 09:49:03

学习!!
页: [1]
查看完整版本: C++基础知识10.栈和队列、互斥锁