标签: stdmutex

std :: unique_lock <std :: mutex>或std :: lock_guard <std :: mutex>?

我有两个用例.

答:我想将两个线程的访问同步到队列.

B.我想将两个线程的访问同步到队列并使用条件变量,因为其中一个线程将等待内容由另一个线程存储到队列中.

对于用例AI,请参阅代码示例std::lock_guard<>.对于用例BI,请参阅使用的代码示例std::unique_lock<>.

两者之间有什么区别,我应该在哪个用例中使用哪一个?

c++ multithreading mutual-exclusion c++11 stdmutex

318
推荐指数
5
解决办法
13万
查看次数

为什么 std::mutex 是标准布局类?

[thread.mutex.class]/3 :

[...]它是一个标准布局类([class.prop])。

提出这个要求的原因是什么?

c++ language-lawyer stdmutex

13
推荐指数
1
解决办法
414
查看次数

为什么 Visual C++ 中的 std::mutex 比 std::shared_mutex 差这么多?

在 Visual Studio 2022 中以发布模式运行以下命令:

#include <chrono>
#include <mutex>
#include <shared_mutex>
#include <iostream>

std::mutex mx;
std::shared_mutex smx;

constexpr int N = 100'000'000;

int main()
{
    auto t1 = std::chrono::steady_clock::now();
    for (int i = 0; i != N; i++)
    {
        std::unique_lock<std::mutex> l{ mx };
    }
    auto t2 = std::chrono::steady_clock::now();
    for (int i = 0; i != N; i++)
    {
        std::unique_lock<std::shared_mutex> l{ smx };
    }
    auto t3 = std::chrono::steady_clock::now();

    auto d1 = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
    auto d2 = std::chrono::duration_cast<std::chrono::duration<double>>(t3 - t2);

    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ stdmutex

13
推荐指数
1
解决办法
2354
查看次数

是否在lock_guard析构函数之前或之后执行了复制返回操作?

get_a()功能安全的比赛条件或者我需要明确地复制str_get_b()为了有一个线程安全的功能?

class Class {
public:
  auto get_a() -> std::string {
    auto&& guard = std::lock_guard{mutex_};
    return str_;
  }
  auto get_b() -> std::string {
    auto&& guard = std::lock_guard{mutex_};
    auto str = str_;
    return str;
  }
private:
  std::mutex mutex_{};
  std::string str_{};
};
Run Code Online (Sandbox Code Playgroud)

注意:我知道Stack Overflow上有类似的问题,但我找不到明确回答这个问题的问题.

c++ destructor thread-safety race-condition stdmutex

9
推荐指数
1
解决办法
186
查看次数

是否有任何理由将C++ 11+ std :: mutex声明为全局变量而不是作为函数参数传递给std :: thread?

我见过大多数使用std::mutex互斥体是全局的例子.我想知道为什么这样做有什么具体的原因?我有自己的程序,我不这样做,只是将互斥量作为一个std::thread std::ref.拥有全局变量不是不好的做法,std::mutexes如果没有语言限制理由这样做,那么C++中全局背后的理性是什么?

c++ multithreading mutex stdthread stdmutex

8
推荐指数
1
解决办法
2647
查看次数

为什么使用std :: mutex的函数会对pthread_key_create的地址进行空检查?

采用这个简单的函数,在由std::mutex以下实现的锁定下递增整数:

#include <mutex>

std::mutex m;

void inc(int& i) {
    std::unique_lock<std::mutex> lock(m);
    i++;
}
Run Code Online (Sandbox Code Playgroud)

我希望这(在内联之后)以直接的方式编译,然后调用m.lock()增量.im.unlock()

检查生成的程序集的最新版本的gccclang,但是,我们看到一个额外的并发症.gcc首先考虑版本:

inc(int&):
  mov eax, OFFSET FLAT:__gthrw___pthread_key_create(unsigned int*, void (*)(void*))
  test rax, rax
  je .L2
  push rbx
  mov rbx, rdi
  mov edi, OFFSET FLAT:m
  call __gthrw_pthread_mutex_lock(pthread_mutex_t*)
  test eax, eax
  jne .L10
  add DWORD PTR [rbx], 1
  mov edi, OFFSET FLAT:m
  pop rbx
  jmp __gthrw_pthread_mutex_unlock(pthread_mutex_t*)
.L2:
  add DWORD PTR [rdi], 1
  ret
.L10:
  mov edi, eax …
Run Code Online (Sandbox Code Playgroud)

c++ gcc pthreads clang stdmutex

8
推荐指数
1
解决办法
609
查看次数

非原子类型如何实现std :: atomic_ref?

我想知道如何才能std::atomic_ref有效地实现std::mutex非原子对象(每个对象一个),因为以下属性似乎很难实施:

相对于通过引用同一对象的任何其他atomic_ref施加的原子操作,通过atomic_ref施加到对象的原子操作是原子的。

特别是以下代码:

void set(std::vector<Big> &objs, size_t i, const Big &val) {
    std::atomic_ref RefI{objs[i]};
    RefI.store(val);
}
Run Code Online (Sandbox Code Playgroud)

似乎很难实现,因为std::atomic_ref每次都需要以某种方式进行选择std::mutex(除非这是由相同类型的所有对象共享的大主锁)。

我想念什么吗?还是每个对象都有责任实施std::atomic_ref,因此要么是原子的要么携带一个std::mutex

c++ stdatomic c++20 stdmutex

8
推荐指数
2
解决办法
102
查看次数

`std :: lock_guard <std :: mutex>`对象没有名称时的不同行为

我正在学习std::mutex,std::thread我对下面两段代码的不同行为感到惊讶:

#include <iostream>
#include <mutex>
#include <thread>
using namespace std;

std::mutex mtx;

void foo(int k)
{
    std::lock_guard<std::mutex> lg{ mtx };
    for (int i = 0; i < 10; ++i)
        cout << "This is a test!" << i << endl;
    cout << "The test " << k << " has been finished." << endl;
}

int main()
{
    std::thread t1(foo, 1);
    std::thread t2(foo, 2);
    t1.join();
    t2.join();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是顺序的.但如果我没有名称变量std::lock_guard<std::mutex>,则输出无序

void foo(int k)
{ …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 stdthread stdmutex

6
推荐指数
1
解决办法
456
查看次数

当缓存行大小通常为 64 字节时,为什么 sizeof std::mutex == 40

在 static_assert 之后,gcc 和 clang 主干都通过了。

#include<mutex>
int main(){
    static_assert(sizeof(std::mutex)==40);
}
Run Code Online (Sandbox Code Playgroud)

由于 x86 CPU 有 64 字节缓存线,我期望互斥锁 sizeof 为 64,因此可以避免错误共享。大小“仅”40 字节是否有原因?

注意:我知道大小也会影响性能,但程序中很少有大量互斥体,因此与错误共享的成本相比,大小开销似乎可以忽略不计。

注意:有一个类似的问题问为什么 std::mutex 这么大,我问为什么它这么小:)

编辑:MSVC 16.7 的大小为 80。

c++ optimization x86 false-sharing stdmutex

6
推荐指数
1
解决办法
288
查看次数

使用互斥锁时,C++ 单例是否需要内存屏障?

我从这里知道互斥锁也可以带来内存屏障的效果:Can mutex Replace Memory Barrier,但我总是看到在 C++ 单例示例中使用了内存屏障,如下所示,内存屏障是不必要的吗?

Singleton* Singleton::getInstance() {
     Singleton* tmp = m_instance.load(std::memory_order_relaxed);
     std::atomic_thread_fence(std::memory_order_acquire);        
     if (tmp == nullptr) {
         std::lock_guard<std::mutex> lock(m_mutex);               // using mutex here
         tmp = m_instance.load(std::memory_order_relaxed);
         if (tmp == nullptr) {
             tmp = new Singleton;
             assert(tmp != nullptr);    
             std::atomic_thread_fence(std::memory_order_release); // using memory barrier here
             m_instance.store(tmp, std::memory_order_relaxed);
         }
     }
     return tmp;
 }
Run Code Online (Sandbox Code Playgroud)

c++ memory-barriers stdmutex

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