相关疑难解决方法(0)

锁定多个std :: mutex'es的最佳方法是什么?

注意:这个问题涉及C++ 11.C++ 17(或更高版本)中相同问题的答案可能已经改变.详情如下:


当我们想要锁定多个时std::mutex,我们使用std::lock().但std::lock()不提供RAII功能.

当我们想以std::mutexRAII方式锁定时,我们使用std::lock_guard.但std::lock_guard不能std::mutex安全地锁定多个's.

有没有办法利用这两种方法的优势,以std::mutexRAII的方式锁定多个?

c++ multithreading c++11

46
推荐指数
1
解决办法
1万
查看次数

std :: lock()是不明确的,不可实现的还是无用的?

(注意:使用std :: lock(c ++ 11)大量CPU负载进行评论时,大部分内容都是多余的,但我认为这个主题应该得到自己的问题和答案.)

我最近遇到了一些示例C++ 11代码:

std::unique_lock<std::mutex> lock1(from_acct.mutex, std::defer_lock);
std::unique_lock<std::mutex> lock2(to_acct.mutex, std::defer_lock);
std::lock(lock1, lock2); // avoid deadlock
transfer_money(from_acct, to_acct, amount);
Run Code Online (Sandbox Code Playgroud)

哇,我想,std::lock听起来很有趣.我想知道它的标准是什么意思?

C++ 11第30.4.3节[thread.lock.algorithm],第(4)和(5)段:

模板空锁(L1&,L2&,L3&...);

4 要求:每个模板参数类型应满足可锁定要求,[注意:unique_lock类模板在适当实例化时满足这些要求. - 结束说明]

5种效果:所有参数通过调用的顺序被锁定lock(), try_lock()unlock()在每个参数.调用序列不应导致死锁,否则不会被指定.[注意:必须使用诸如try-and-back-off之类的死锁避免算法,但未指定特定算法以避免过度约束实现.- 结束注释]如果调用lock()try_lock()抛出异常,unlock()则应调用已被lock()或调用锁定的任何参数try_lock().

请考虑以下示例.称之为"示例1":

Thread 1                    Thread 2
std::lock(lock1, lock2);    std::lock(lock2, lock1);
Run Code Online (Sandbox Code Playgroud)

这可能是僵局吗?

对标准的简单解读说"不".大!也许编译器可以为我订购我的锁,这将是一种整洁.

现在尝试例2:

Thread 1                                  Thread 2
std::lock(lock1, lock2, lock3, lock4);    std::lock(lock3, lock4); …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading language-lawyer c++11

28
推荐指数
2
解决办法
5459
查看次数

使用atomic_flag自旋锁进行内存排序

我试图熟悉c ++ 11的新内存排序概念,并相信我对它们有很好的把握,直到我偶然发现了自旋锁的这种实现:

#include <atomic>

namespace JayZ
{
    namespace Tools
    {
        class SpinLock
        {
        private:
            std::atomic_flag spin_lock;
        public:
            inline SpinLock( void ) : atomic_flag( ATOMIC_FLAG_INIT ) {}

            inline void lock( void )
            {
                while( spin_lock.test_and_set( std::memory_order_acquire ) )
                    ;
            }

            inline void unlock( void )
            {
                lock.clear( std::memory_order_release );
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,在http://en.cppreference.com/w/cpp/atomic/atomic_flag
和"并行行动"一书中提到了相同的内容.我也在SO的某处找到了它.

但我只是不明白它为什么会起作用!
想象一下,线程1调用lock(),test_and_set()返回0作为旧值 - >线程1获得锁定.
但随后线程2出现并尝试相同.现在因为没有发生"存储同步"(release,seq_cst_acq_rel),所以线程1的spin_lock存储应该是轻松的类型.
但是由此得出它不能与线程2的spin_lock读取同步.这应该使线程2能够从spin_lock读取值0,从而获得锁定.
我的错误在哪里?

c++ atomic c++11

5
推荐指数
1
解决办法
3425
查看次数

std :: unique_lock :: release的用例是什么?

在什么情况下会使用这种release方法std::unique_lock?我犯了使用release方法而不是方法的错误,unlock并花了一些时间来理解为什么以下代码不起作用.

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

std::mutex mtx;

void foo()
{    
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "in critical section\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
    lock.release();
}

int main()
{
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i)
        threads.push_back(std::thread(foo));

    for (std::thread& t : threads)
        t.join();
}
Run Code Online (Sandbox Code Playgroud)

c++ multithreading locking c++11

5
推荐指数
2
解决办法
852
查看次数

标签 统计

c++ ×4

c++11 ×4

multithreading ×3

atomic ×1

language-lawyer ×1

locking ×1