63 C++ 多线程 timed_mutex,recursive_timed_mutex

前提 :以往的mutex如果拿锁子拿不到,就会一直等待。

timed_mutex 和 recursive_timed_mutex则不同,这两个提供了方法,可以不一直等待。

try() 方法--mutex 和 timed_mutex 都有,且说明都一样


bool try_lock();
  (C++11 起) 
   

尝试锁定互斥。立即返回。成功获得锁时返回 true ,否则返回 false 。

允许此函数虚假地失败而返回 false ,即使互斥当前未为任何其他线程所锁定。

若已占有 mutex 的线程调用 try_lock ,则行为未定义。

若此操作返回 true ,则同一互斥上的先前 unlock() 操作同步于(定义于 std::memory_order )它。注意若此操作返回 false ,则先前的 lock() 不与之同步。

参数

(无)

返回值

若成功取得锁则为 true ,否则为 false 。

try_lock_for()


template< class Rep, class Period >
bool try_lock_for( const std::chrono::duration<Rep,Period>& timeout_duration );
  (C++11 起) 
   

尝试锁互斥。阻塞直到经过指定的 timeout_duration 或得到锁,取决于何者先到来。成功获得锁时返回 true , 否则返回 false 。

若 timeout_duration 小于或等于 timeout_duration.zero() ,则函数表现同 try_lock() 。

由于调度或资源争议延迟,此函数可能阻塞长于 timeout_duration 。

标准推荐用 steady_clock 度量时长。若实现用 system_clock 代替,则等待时间亦可能对时钟调整敏感。

同 try_lock() ,允许此函数虚假地失败并返回 false ,即使在 timeout_duration 中某点互斥不为任何线程所锁定。

若此操作返回 true ,则同一互斥上先前的 unlock() 调用同步于(定义于 std::memory_order )它。

若已占有 mutex 的线程调用 try_lock_for ,则行为未定义。

std::mutex cout_mutex; // 控制到 std::cout 的访问
std::timed_mutex mutex;
 
void job(int id) 
{
    using Ms = std::chrono::milliseconds;
    std::ostringstream stream;
 
    for (int i = 0; i < 3; ++i) {
        if (mutex.try_lock_for(Ms(100))) {
            stream << "success ";
            std::this_thread::sleep_for(Ms(100));
            mutex.unlock();
        } else {
            stream << "failed ";
        }
        std::this_thread::sleep_for(Ms(100));
    }
 
    std::lock_guard<std::mutex> lock(cout_mutex);
    std::cout << "[" << id << "] " << stream.str() << "\n";
}
 
int main() 
{
    std::vector<std::thread> threads;
    for (int i = 0; i < 4; ++i) {
        threads.emplace_back(job, i);
    }
 
    for (auto& i: threads) {
        i.join();
    }
}

try_lock_until()

std::timed_mutex::try_lock_until









template< class Clock, class Duration >
bool try_lock_until( const std::chrono::time_point<Clock,Duration>& timeout_time );
  (C++11 起) 
   

尝试所互斥。阻塞直至抵达指定的 timeout_time 或得到锁,取决于何者先到来。成功获得锁时返回 true ,否则返回 false 。

若已经过 timeout_time ,则此函数表现同 try_lock() 。

Clock 必须符合时钟 (Clock) 要求。若 std::chrono::is_clock_v<Clock> 为 false 则程序为非良构。 (C++20 起)

标准推荐使用绑定到 timeout_time 的时钟,该情况下可以计入时钟的调整。从而在调用时刻,阻塞的时长可以,但也可以不,小于或大于 timeout_time - Clock::now() 。这取决于调整的方向以及实现是否尊重它。函数亦可能由于调度或资源纠纷延迟,而阻塞长于到抵达 timeout_time 之后。

同 try_lock() ,允许此函数虚假地失败并返回 false ,即使在 timeout_time 前的某点任何线程都不锁定互斥。

若此操作返回 true ,则同一互斥上先前的 unlock() 调用同步于(定义于 std::memory_order )它。

若已占有 mutex 的线程调用 try_lock_until ,则行为未定义。

#include <thread>
#include <iostream>
#include <chrono>
#include <mutex>
 
std::timed_mutex test_mutex;
 
void f()
{
    auto now=std::chrono::steady_clock::now();
    test_mutex.try_lock_until(now + std::chrono::seconds(10));
    std::cout << "hello world\n";
}
 
int main()
{
    std::lock_guard<std::timed_mutex> l(test_mutex);
    std::thread t(f);
    t.join();
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shared_timed_mutexC++标准库中的一种锁类型,它是std::shared_mutex的一种变体。与std::shared_mutex相比,shared_timed_mutex提供了带有时间限制的锁定操作,类似于std::timed_mutex。\[2\]这意味着线程可以尝试在一定时间内获取shared_timed_mutex的锁,如果超过了指定的时间仍未获取到锁,则可以选择放弃或进行其他处理。 std::shared_mutex通常用于多个读线程可以同时访问同一资源而不导致数据竞争,但只有一个写线程能访问的情况。\[3\]它提供了两种锁定操作:lock_shared()用于读取共享数据,而lock()用于写入共享数据。当有一个写线程调用lock()时,所有的读线程都会等待该写线程释放锁。这种机制可以有效地保护共享数据的一致性。 需要注意的是,由于其额外的复杂性,std::shared_mutex和std::shared_timed_mutex相对于普通锁std::mutex和std::timed_mutex的使用情况比较少见。但在某些特定的场景下,它们确实是有用的。\[1\]如果你需要在多个读线程和一个写线程之间进行同步,并且需要支持带有时间限制的锁定操作,那么可以考虑使用shared_timed_mutex。 #### 引用[.reference_title] - *1* *2* *3* [C++ 多线程:互斥量(mutex)](https://blog.csdn.net/iuices/article/details/123099747)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值