c++ - 跳转到案例标签跨越 'std::unique_lock<std::mutex>' 的初始化

标签 c++

我正在使用条件变量学习两个线程之间的线程同步,但出现此编译错误:

CVV.cpp:21:3: error: jump to case label [-fpermissive]
   default:
   ^
CVV.cpp:14:33: error:   crosses initialization of ‘std::unique_lock<std::mutex> ul’
    std::unique_lock<std::mutex> ul(m, std::defer_lock);

这是我的代码

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

std::mutex m;
std::condition_variable cv;

void recv_data() {
    int32_t opn_type;
    
    switch(opn_type) {
        case 1:
            std::unique_lock<std::mutex> ul(m);
            // do processing and add to queue
            cv.notify_one();
            ul.unlock();
            
            break;
            
        default:
            break;
    }
}

int32_t main() {
    std::thread th(recv_data);
    th.join();
    
    return EXIT_SUCCESS;
}

谁能解释一下我做错了什么

最佳答案

switch(opn_type) {
    case 1: {
        std::unique_lock<std::mutex> ul(m);
        // do processing and add to queue
        cv.notify_one();
        ul.unlock();
        
    }   break;
        
    default:
        break;
}

case 标签不会结束变量生命周期,因此 ul 存在并在 default: 之后销毁,但仅在 case 1: 内初始化。

把它放在一个 block 中。

switch(opn_type) {
  case 1: {
    std::unique_lock<std::mutex> ul(m);
    // do processing and add to queue
    cv.notify_one();
  }   break;
    
  default:
    break;
}

.unlock() 什么都不做,因为范围就在那里结束。在这个版本中,我删除了它。

请注意,我发现将线程原语与其他代码混合使用很危险。

template<class T>
struct threadsafe_queue {
  T pop() {
    auto l = lock();
    cv.wait(lk, [&]{return !queue.empty();});
    T retval = queue.front();
    queue.pop_front();
    return retval;
  }
  void push( T in ) {
    auto l = lock(m);
    queue.push_back(std::move(in));
    cv.notify_one();
  }
  std::deque<T> pop_all() {
    auto l = lock();
    return std::move(queue);
  }
private:
  mutable std::mutex m;
  std::condition_variable cv;
  std::deque<T> queue;
  std::unique_lock<std::mutex> lock() const {
    return std::unique_lock<std::mutex>(m);
  }
};

添加“try_pop”、“try_pop_for”等是一个练习。

关于c++ - 跳转到案例标签跨越 'std::unique_lock<std::mutex>' 的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65360812/

相关文章:

c++ - 常量引用时奇怪的字符串行为

c++ - 带有 float 的自定义内核 GpuMat

c++ - 使用特征矩阵作为特征数组引用的参数

c++空队列初始化在Qt Creator中不为空

c++ - 解释 C++/SDL2 程序的 valgrind 输出

c++ - 在 OpenCV 中,有没有比 cv::merge 和 cv::split 更有效地组合/分离图像 channel 的方法?

c++ - 为什么没有 to_string(const string&)?

c++ - 如何使用 MAP 创建类?? C++

c++ - Emacs 右对齐 ')'

c++ - 处理 float 不准确