

不正常情况说明::
线程1执行第一行50移动到eax
然后切换线程2,线程2全部执行完成++为51;
切换线程1,执行eax++也就是50+1=51
join和detach区别:

#include <iostream>
#include <thread>
#include <windows.h>
void foo()
{
std::cout << "Run New thread!\n";
Sleep(2000); //需要头文件<windows.h>
}
int main()
{
std::thread t(foo);
if (t.joinable())
{
t.join(); // 等待线程t执行完毕
//t.detach(); // 分离线程t与主线程
}
std::cout << "Run Main thread!\n";
return 0;
}
join:先显示new,过两秒显示main

互斥锁mutex
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int num = 0;
void thread_function(int& n)
{
for (int i = 0; i < 100; ++i)
{
mtx.lock();
n++;
mtx.unlock();
}
}
int main()
{
std::thread myThread[500];
for (std::thread& a : myThread)
{
a = std::thread(thread_function, std::ref(num));
a.join();
}
std::cout << "num = " << num << std::endl;
std::cout << "Main thread exits!" << std::endl;
return 0;
}
代码的目标是让多个线程(500个线程)同时对一个共享变量num进行递增操作
-
使用
std::ref(num)确保num是按引用传递给thread_function的,而不是传递一个副本。

lock_guard:
用于实现资源的自动加锁和解锁。它是基于RAII(资源获取即初始化)的设计理念,能够确保在作用域结束时自动释放锁资源,避免了手动管理锁的复杂性和可能出现的错误。
std::lock_guard的主要特点如下:
自动加锁: 在创建std::lock_guard对象时,会立即对指定的互斥量进行加锁操作。这样可以确保在进入作用域后,互斥量已经被锁定,避免了并发访问资源的竞争条件。
自动解锁:std::lock_guard对象在作用域结束时,会自动释放互斥量。无论作用域是通过正常的流程结束、异常抛出还是使用return语句提前返回,std::lock_guard都能保证互斥量被正确解锁,避免了资源泄漏和死锁的风险。
适用于局部锁定: 由于std::lock_guard是通过栈上的对象实现的,因此适用于在局部范围内锁定互斥量。当超出std::lock_guard对象的作用域时,互斥量会自动解锁,释放控制权。
使用std::lock_guard的一般步骤如下:
创建一个std::lock_guard对象,传入要加锁的互斥量作为参数。
执行需要加锁保护的代码块。
std::lock_guard对象的作用域结束时,自动调用析构函数解锁互斥量。


需要在自己需要的作用域加一个大括号,太麻烦了,引出unique lock

unique_lock
std::unique_lock是C++标准库中的一个模板类,用于实现更加灵活的互斥量的加锁和解锁操作。它提供了比std::lock_guard更多的功能和灵活性。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // 互斥量
void thread_function()
{
std::unique_lock<std::mutex> lock(mtx); // 加锁互斥量
std::cout << "Thread running" << std::endl;
// 执行需要加锁保护的代码
lock.unlock(); // 手动解锁互斥量
// 执行不需要加锁保护的代码
lock.lock(); // 再次加锁互斥量
// 执行需要加锁保护的代码
}
// unique_lock对象的析构函数自动解锁互斥量
int main()
{
std::thread t1(thread_function);
t1.join();
std::cout << "Main thread exits!" << std::endl;
return 0;
}
条件变量:

#include <iostream>
#include <thread>
#include <condition_variable>
std::mutex mtx; // 互斥量
std::condition_variable cv; // 条件变量
bool isReady = false; // 条件
void thread_function()
{
std::unique_lock<std::mutex> lock(mtx);
while (!isReady)
{
cv.wait(lock); // 等待条件满足
}
std::cout << "Thread is notified" << std::endl;
}
int main()
{
std::thread t(thread_function);
// 模拟一段耗时操作
std::this_thread::sleep_for(std::chrono::seconds(2));
{
std::lock_guard<std::mutex> lock(mtx);
isReady = true; // 设置条件为true
}
cv.notify_one(); // 通知等待的线程
t.join();
return 0;
}
创建了一个线程,该线程在等待状态下通过cv.wait(lock)等待条件满足。主线程经过一段时间后将条件设置为true,然后通过cv.notify_one()通知等待的线程。等待的线程被唤醒后输出一条消息。有wait就要有通知notify不然不会指执行

一样的

读写锁
#include <iostream>
#include <thread>
#include <vector>
#include <shared_mutex>
std::shared_mutex rw_mutex; // 读写锁
int shared_data = 0; // 共享数据
// 读操作
void read_data(int id) {
std::shared_lock<std::shared_mutex> lock(rw_mutex); // 获取共享锁
std::cout << "Reader " << id << " sees value: " << shared_data << std::endl;
}
// 写操作
void write_data(int id, int value) {
std::unique_lock<std::shared_mutex> lock(rw_mutex); // 获取独占锁
std::cout << "Writer " << id << " is writing value: " << value << std::endl;
shared_data = value;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟写操作
}
int main() {
const int num_readers = 5;
const int num_writers = 2;
std::vector<std::thread> readers;
std::vector<std::thread> writers;
// 创建读线程
for (int i = 0; i < num_readers; ++i) {
readers.emplace_back(read_data, i);
}
// 创建写线程
for (int i = 0; i < num_writers; ++i) {
writers.emplace_back(write_data, i, i + 100);
}
// 等待所有线程完成
for (auto& t : readers) {
t.join();
}
for (auto& t : writers) {
t.join();
}
std::cout << "Final shared data value: " << shared_data << std::endl;
std::cout << "Main thread exits!" << std::endl;
return 0;
}



被折叠的 条评论
为什么被折叠?



