C++多线程中的互斥锁

开发
C++标准库提供了多种类型的互斥锁,每种锁都有其特定的用途和特点。选择合适的互斥锁类型可以有效提高程序的并发性能和安全性。

在多线程编程中,互斥锁(mutex)是确保线程安全、避免数据竞争的重要工具。C++标准库提供了多种互斥锁,每种都有其特定的应用场景和特点。

主要有以下几种互斥锁(Mutex):

  • std::mutex:最基本的互斥锁,用于保护临界区,确保同一时间只有一个线程可以访问被保护的资源。
  • std::timed_mutex:支持超时机制的互斥锁,可以尝试在给定时间内锁定互斥锁。如果在指定时间内没有成功获取锁,则返回失败。
  • std::recursive_mutex:递归互斥锁,同一线程可以多次获取锁而不会发生死锁,通常用于递归函数中。
  • std::recursive_timed_mutex:支持超时机制的递归互斥锁,结合了递归锁和超时锁的特性。
  • std::shared_mutex(C++17 引入):允许多个线程同时读取,但只有一个线程可以写入。适用于读多写少的场景。
  • std::shared_timed_mutex(C++17 引入):支持超时机制的共享互斥锁,可以在给定时间内尝试获取读锁或写锁。

这些是C++标准库中提供的几种主要的互斥锁类型。每种锁都有其特定的应用场景和使用方法,选择合适的互斥锁类型对于实现高效、安全的多线程程序非常重要。

一、基本互斥锁(std::mutex)

std::mutex是最基本的互斥锁,主要用于保护临界区,确保同一时间只有一个线程可以访问共享资源。

特点:

  • 简单易用,适用于大多数场景。
  • 不能递归锁定,同一线程多次尝试锁定会导致死锁。

示例代码:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void print_thread_id(int id) {
    std::lock_guard<std::mutex> lock(mtx); // 自动管理锁的获取和释放
    std::cout << "Thread ID: " << id << std::endl;
}

int main() {
    std::thread t1(print_thread_id, 1);
    std::thread t2(print_thread_id, 2);

    t1.join();
    t2.join();

    return 0;
}

二、带超时机制的互斥锁(std::timed_mutex)

std::timed_mutex在std::mutex的基础上增加了超时功能,允许线程在指定时间内尝试获取锁,如果在超时时间内未成功获取锁,则返回失败。

特点:

  • 适用于需要设置锁获取超时时间的场景。
  • 提供try_lock_for和try_lock_until两种超时尝试获取锁的方法。

示例代码:

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>

std::timed_mutex tmtx;

void try_to_lock(int id) {
    if(tmtx.try_lock_for(std::chrono::milliseconds(100))) {
        std::cout << "Thread " << id << " locked the mutex" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        tmtx.unlock();
    } else {
        std::cout << "Thread " << id << " could not lock the mutex" << std::endl;
    }
}

int main() {
    std::thread t1(try_to_lock, 1);
    std::thread t2(try_to_lock, 2);

    t1.join();
    t2.join();

    return 0;
}

三、递归互斥锁(std::recursive_mutex)

std::recursive_mutex允许同一线程多次获取锁而不会发生死锁,这对于递归函数或需要多次锁定的场景非常有用。

特点:

  • 适用于递归调用和需要多次锁定的场景。
  • 需要注意避免滥用,因为递归锁的使用会增加锁定次数的复杂性。

示例代码:

#include <iostream>
#include <thread>
#include <mutex>

std::recursive_mutex rmtx;

void recursive_function(int depth) {
    rmtx.lock();
    std::cout << "Depth: " << depth << std::endl;
    if (depth > 0) {
        recursive_function(depth - 1);
    }
    rmtx.unlock();
}

int main() {
    std::thread t(recursive_function, 5);
    t.join();

    return 0;
}

四、带超时机制的递归互斥锁(std::recursive_timed_mutex)

std::recursive_timed_mutex结合了std::recursive_mutex和std::timed_mutex的特性,支持递归锁定和超时机制。

特点:

  • 适用于递归调用和需要超时机制的场景。
  • 提供超时尝试获取递归锁的方法。

示例代码:

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>

std::recursive_timed_mutex rtmmtx;

void try_recursive_lock(int id, int depth) {
    if (rtmmtx.try_lock_for(std::chrono::milliseconds(100))) {
        std::cout << "Thread " << id << " locked at depth " << depth << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        if (depth > 0) {
            try_recursive_lock(id, depth - 1);
        }
        rtmmtx.unlock();
    } else {
        std::cout << "Thread " << id << " could not lock at depth " << depth << std::endl;
    }
}

int main() {
    std::thread t1(try_recursive_lock, 1, 3);
    std::thread t2(try_recursive_lock, 2, 3);

    t1.join();
    t2.join();

    return 0;
}

五、共享互斥锁(std::shared_mutex)

std::shared_mutex允许多个线程同时读取,但只有一个线程可以写入。这在读多写少的场景下非常有用。

特点:

  • 适用于读多写少的场景。
  • 读操作和写操作使用不同的锁定机制。

示例代码:


#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex shmtx;

void read_shared(int id) {
    std::shared_lock<std::shared_mutex> lock(shmtx); // 共享锁
    std::cout << "Thread " << id << " is reading" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

void write_shared(int id) {
    std::unique_lock<std::shared_mutex> lock(shmtx); // 独占锁
    std::cout << "Thread " << id << " is writing" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

int main() {
    std::thread readers[5], writer(write_shared, 1);

    for (int i = 0; i < 5; ++i) {
        readers[i] = std::thread(read_shared, i + 2);
    }

    writer.join();
    for (auto& reader : readers) {
        reader.join();
    }

    return 0;
}

六、带超时机制的共享互斥锁(std::shared_timed_mutex)

std::shared_timed_mutex结合了std::shared_mutex和std::timed_mutex的特性,支持超时机制。

特点:

  • 适用于读多写少且需要超时机制的场景。
  • 提供超时尝试获取共享锁的方法。

示例代码:


#include <iostream>
#include <thread>
#include <shared_mutex>
#include <chrono>

std::shared_timed_mutex shtmmtx;

void try_read_shared(int id) {
    if (shtmmtx.try_lock_shared_for(std::chrono::milliseconds(100))) {
        std::cout << "Thread " << id << " is reading" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        shtmmtx.unlock_shared();
    } else {
        std::cout << "Thread " << id << " could not read" << std::endl;
    }
}

void try_write_shared(int id) {
    if (shtmmtx.try_lock_for(std::chrono::milliseconds(100))) {
        std::cout << "Thread " << id << " is writing" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        shtmmtx.unlock();
    } else {
        std::cout << "Thread " << id << " could not write" << std::endl;
    }
}

int main() {
    std::thread readers[5], writer(try_write_shared, 1);

    for (int i = 0; i < 5; ++i) {
        readers[i] = std::thread(try_read_shared, i + 2);
    }

    writer.join();
    for (auto& reader : readers) {
        reader.join();
    }

    return 0;
}

总结

C++标准库提供了多种类型的互斥锁,每种锁都有其特定的用途和特点。选择合适的互斥锁类型可以有效提高程序的并发性能和安全性。

责任编辑:赵宁宁 来源: AI让生活更美好
相关推荐

2020-08-26 08:59:58

Linux线程互斥锁

2024-06-28 08:45:58

2023-12-14 15:05:08

volatile代码C++

2024-10-14 16:25:59

C#线程锁代码

2012-05-18 10:36:20

CC++编程

2021-03-24 08:02:58

C语言

2010-01-18 14:09:58

C++多线程

2010-02-04 10:19:39

C++多线程

2010-02-05 15:30:54

C++多线程测试

2021-02-25 15:58:46

C++线程编程开发技术

2021-03-05 07:38:52

C++线程编程开发技术

2024-06-24 12:57:09

多线程C++编程语言

2024-10-21 16:59:37

C#编程多线程

2024-11-05 16:29:57

2011-04-25 14:42:10

C#lock

2011-06-14 15:25:28

C++多线程

2024-02-02 18:29:54

C++线程编程

2023-06-02 08:29:24

https://wwMutex

2023-10-24 09:03:05

C++编程

2018-10-25 15:55:44

Java多线程锁优化
点赞
收藏

51CTO技术栈公众号