小编wod*_*der的帖子

使用互斥锁时,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
查看次数

在 C++ 中,函数什么时候会包含堆栈 _Unwind_Resume 调用?

我现在正在学习c++异常,遇到了麻烦,程序如下

#include<iostream>
#include<unistd.h>
#include<string>
#include<thread>
#include<vector>
#include<exception>
using namespace std;


vector<int> vec(20);


void fn()throw() {
        vec.at(10);
}

int main(){
        fn();

return 0;
}

Run Code Online (Sandbox Code Playgroud)

我使用 gdb 反汇编fn(),我们可以看到callq 0x4008d0 _Unwind_Resume@plt,这是对堆栈展开操作的调用,因为 vector::at 可能会抛出超出范围的异常

Dump of assembler code for function fn():
   0x00000000004009e6 <+0>:     push   %rbp
   0x00000000004009e7 <+1>:     mov    %rsp,%rbp
   0x00000000004009ea <+4>:     mov    $0xa,%esi
   0x00000000004009ef <+9>:     mov    $0x6020a0,%edi
   0x00000000004009f4 <+14>:    callq  0x400ba6 <std::vector<int, std::allocator<int> >::at(unsigned long)>
   0x00000000004009f9 <+19>:    jmp    0x400a11 <fn()+43>
   0x00000000004009fb <+21>:    cmp    $0xffffffffffffffff,%rdx
   0x00000000004009ff <+25>:    je     0x400a09 <fn()+35>
   0x0000000000400a01 …
Run Code Online (Sandbox Code Playgroud)

c++ gcc exception

4
推荐指数
1
解决办法
1924
查看次数

为什么在 C++ 中互斥锁可以锁定两次而不解锁?

int main(){

        std::mutex mut;
        mut.lock();
        cout<<"1111\n";
        mut.lock();      
        cout<<"2222\n";
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么这段代码能工作并输出2222?它不应该在第二个 lock() 处阻塞吗?在互斥锁源码中,操作锁抛出异常。它不应该阻塞并等待吗?我try{...}catch(exception& e){}用来捕捉这个异常,但它不起作用。

    void
    lock()
    {
      int __e = __gthread_mutex_lock(&_M_mutex);

      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
      if (__e)
    __throw_system_error(__e);
    }
Run Code Online (Sandbox Code Playgroud)

c++

4
推荐指数
1
解决办法
359
查看次数

为什么使用原子 CAS 的程序不能保持线程安全?


int main(){

    atomic<bool> atomic_lock(false);
    std::atomic_flag lock_flag = ATOMIC_FLAG_INIT;
    int count = 0;


    auto f = [&](){
        bool flag = false;
        
        for( int i = 0; i< 10000000; ++i){
          while(!atomic_lock.compare_exchange_strong(flag, true)){}
          //while(lock_flag.test_and_set(std::memory_order_seq_cst));

          ++count;
          //lock_flag.clear(std::memory_order_seq_cst);
          atomic_lock.store(false, std::memory_order_seq_cst);
        }
    };

    thread t1(f);
    thread t2(f);
    t1.join();
    t2.join();

    cout<<count<<endl;

    return 0;
}

Run Code Online (Sandbox Code Playgroud)

这是我的程序,我想用 CAS 替换互斥锁,但不是 20000000 的输出表明它不是线程安全程序,哪里错了?但是,我用 atomic_flag 替换 atomic 显示如上,输出是正确的

c++ thread-safety c++11 stdatomic

2
推荐指数
1
解决办法
70
查看次数

为什么 std::vector 允许使用 [] 进行分配,但 size() 和 capacity() 没有改变?

我进行了如下测试,创建一个向量并将其容量设置为 1,然后用于v[100]=100;直接分配 v[100] 但不触发核心转储,为什么?向量v应该没有足够的内存来访问v[100],但是v[100]成功被赋值为100,并且size和capacity()保持为0和1,如何理解?

int main(){
    std::vector<int> v;
    v.reserve(1); 
    v[100]=100;                      //here does't triggle core dump, wired
    std::cout<<v.size()<<std::endl;  //0 
    std::cout<<v.capacity()<<std::endl; //1
    std::cout<<v[100]<<std::endl;    //100
return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ stl vector

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