C++多线程编程中的锁详解

在现代软件开发中,多线程编程是提升应用程序性能和响应能力的重要手段。然而,多线程编程也带来了数据竞争和死锁等复杂问题。为了确保线程间的同步和共享数据的一致性,C++标准库提供了多种锁机制。

1. std::mutex

std::mutex是最基础的互斥锁,用于保护共享数据,防止多个线程同时访问该数据。

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

std::mutex mtx;

void print_thread_id(int id) {
    mtx.lock();
    std::cout << "Thread " << id << std::endl;
    mtx.unlock();
}

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

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

    return 0;
}

在上述代码中,mtx.lock()mtx.unlock()分别用于加锁和解锁,确保同一时刻只有一个线程可以访问临界区(std::cout操作)。

2. std::recursive_mutex

std::recursive_mutex允许同一线程多次获得同一锁,而不会导致死锁。适用于递归调用中需要加锁的场景。

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

std::recursive_mutex rec_mtx;

void recursive_function(int count) {
    if (count <= 0) return;
    rec_mtx.lock();
    std::cout << "Count: " << count << std::endl;
    recursive_function(count - 1);
    rec_mtx.unlock();
}

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

    return 0;
}

3. std::timed_mutex

std::timed_mutex支持尝试在一定时间内获取锁。这在避免死锁和提高程序响应性方面很有用。

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

std::timed_mutex tmtx;

void try_lock_for_example() {
    if (tmtx.try_lock_for(std::chrono::seconds(1))) {
        std::cout << "Lock acquired" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        tmtx.unlock();
    } else {
        std::cout << "Failed to acquire lock" << std::endl;
    }
}

int main() {
    std::thread t1(try_lock_for_example);
    std::thread t2(try_lock_for_example);

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

    return 0;
}

4. std::recursive_timed_mutex

std::recursive_timed_mutex结合了std::recursive_mutexstd::timed_mutex的特性

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

std::recursive_timed_mutex rtmtx;

void recursive_timed_function(int count) {
    if (count <= 0) return;
    if (rtmtx.try_lock_for(std::chrono::seconds(1))) {
        std::cout << "Count: " << count << std::endl;
        recursive_timed_function(count - 1);
        rtmtx.unlock();
    } else {
        std::cout << "Failed to acquire lock" << std::endl;
    }
}

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

    return 0;
}

5. std::shared_mutex(C++17引入)

std::shared_mutex允许多个线程同时读取共享数据,但只允许一个线程写入数据。这种机制适用于读多写少的场景。

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

std::shared_mutex smtx;

void read_function() {
    smtx.lock_shared();
    std::cout << "Reading data" << std::endl;
    smtx.unlock_shared();
}

void write_function() {
    smtx.lock();
    std::cout << "Writing data" << std::endl;
    smtx.unlock();
}

int main() {
    std::thread t1(read_function);
    std::thread t2(read_function);
    std::thread t3(write_function);

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

    return 0;
}

6. std::shared_timed_mutex(C++14引入)

std::shared_timed_mutex结合了std::shared_mutexstd::timed_mutex的特性。

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

std::shared_timed_mutex stmtx;

void shared_timed_read_function() {
    if (stmtx.try_lock_shared_for(std::chrono::seconds(1))) {
        std::cout << "Reading data" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        stmtx.unlock_shared();
    } else {
        std::cout << "Failed to acquire shared lock" << std::endl;
    }
}

void shared_timed_write_function() {
    if (stmtx.try_lock_for(std::chrono::seconds(1))) {
        std::cout << "Writing data" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        stmtx.unlock();
    } else {
        std::cout << "Failed to acquire exclusive lock" << std::endl;
    }
}

int main() {
    std::thread t1(shared_timed_read_function);
    std::thread t2(shared_timed_read_function);
    std::thread t3(shared_timed_write_function);

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

    return 0;
}

7. std::lock_guard

std::lock_guard提供一种异常安全的方式来管理锁的生命周期,通常用于自动解锁。

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

std::mutex mtx;

void lock_guard_example() {
    std::lock_guard<std::mutex> lock(mtx);
    std::cout << "Lock acquired using lock_guard" << std::endl;
    // mtx is automatically unlocked when lock goes out of scope
}

int main() {
    std::thread t(lock_guard_example);
    t.join();

    return 0;
}

8. std::unique_lock

std::unique_lockstd::lock_guard更加灵活,支持延迟加锁、解锁和重新加锁。

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

std::mutex mtx;

void unique_lock_example() {
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "Lock acquired using unique_lock" << std::endl;
    lock.unlock();
    std::cout << "Lock released" << std::endl;
    lock.lock();
    std::cout << "Lock reacquired" << std::endl;
}

int main() {
    std::thread t(unique_lock_example);
    t.join();

    return 0;
}

9. std::shared_lock(C++17引入)

std::shared_lock用于管理共享互斥量(std::shared_mutexstd::shared_timed_mutex),提供了一种简单的方式来处理读锁。

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

std::shared_mutex smtx;

void shared_lock_example() {
    std::shared_lock<std::shared_mutex> lock(smtx);
    std::cout << "Shared lock acquired" << std::endl;
}

int main() {
    std::thread t1(shared_lock_example);
    std::thread t2(shared_lock_example);

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

    return 0;
}

结论

C++标准库提供了多种锁机制,帮助开发者在多线程环境中确保数据的一致性和线程的同步。根据具体的应用场景选择合适的锁,可以有效地避免数据竞争和死锁问题,从而编写出高效、安全的多线程程序。

  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值