我正在使用条件变量学习两个线程之间的线程同步,但出现此编译错误:
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/