Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
线程安全堆栈互斥在忙时被破坏 我一直在学习C++标准库多线程的一段时间,作为一个练习,我想使用互斥阻塞和条件变量来做一个线程安全的堆栈。这是我上的课: #ifndef THREADSAFE_STACK_H_ #define THREADSAFE_STACK_H_ #include <mutex> #include <condition_variable> #include <stack> #include <memory> template <typename T> class threadsafe_stack { public: mutable std::mutex mut; std::stack<T> st; std::condition_variable cond; public: threadsafe_stack() = default; threadsafe_stack(const threadsafe_stack &s); threadsafe_stack(threadsafe_stack &&s); threadsafe_stack& operator=(const threadsafe_stack &s); threadsafe_stack& operator=(threadsafe_stack &&s); void push(const T &t); void push(T &&t); bool try_pop(T &t); std::shared_ptr<T> try_pop(); void wait_and_pop(T &t); std::shared_ptr<T> wait_and_pop(); typename std::stack<T>::size_type size() const; bool empty() const; }; template <typename T> threadsafe_stack<T>::threadsafe_stack(const threadsafe_stack &s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); st = s.st; } template <typename T> threadsafe_stack<T>::threadsafe_stack(threadsafe_stack &&s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); st = std::move(s.st); } template <typename T> threadsafe_stack<T>& threadsafe_stack<T>::operator=(const threadsafe_stack &s) { if (this == &s) return *this; std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); s = s.st; return *this; } template <typename T> threadsafe_stack<T>& threadsafe_stack<T>::operator=(threadsafe_stack &&s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); s = std::move(s.st); } template <typename T> void threadsafe_stack<T>::push(const T &t) { std::lock_guard<std::mutex> lock(mut); st.push(t); cond.notify_one(); } template <typename T> void threadsafe_stack<T>::push(T &&t) { std::lock_guard<std::mutex> lock(mut); st.push(std::move(t)); cond.notify_one(); } template <typename T> bool threadsafe_stack<T>::try_pop(T &t) { std::lock_guard<std::mutex> lock(mut); if (st.empty()) return false; t = st.top(); st.pop(); return true; } template <typename T> std::shared_ptr<T> threadsafe_stack<T>::try_pop() { std::lock_guard<std::mutex> lock(mut); if (st.empty()) return std::shared_ptr<T>(); std::shared_ptr<T> result(new T{st.top}); st.pop(); return result; } template <typename T> void threadsafe_stack<T>::wait_and_pop(T &t) { std::unique_lock<std::mutex> lock(mut); cond.wait(lock, [this]{ return !st.empty(); }); t = st.top(); st.pop(); } template <typename T> std::shared_ptr<T> threadsafe_stack<T>::wait_and_pop() { std::unique_lock<std::mutex> lock(mut); cond.wait(lock, [this]{ return !st.empty(); }); std::shared_ptr<T> result(new T{ st.top }); st.pop(); return result; } template <typename T> typename std::stack<T>::size_type threadsafe_stack<T>::size() const { std::lock_guard<std::mutex> lock(mut); return st.size(); } template <typename T> bool threadsafe_stack<T>::empty() const { std::lock_guard<std::mutex> lock(mut); return st.empty(); } #endif_C++_Multithreading_Thread Safety_Stack_Mutex - Fatal编程技术网

线程安全堆栈互斥在忙时被破坏 我一直在学习C++标准库多线程的一段时间,作为一个练习,我想使用互斥阻塞和条件变量来做一个线程安全的堆栈。这是我上的课: #ifndef THREADSAFE_STACK_H_ #define THREADSAFE_STACK_H_ #include <mutex> #include <condition_variable> #include <stack> #include <memory> template <typename T> class threadsafe_stack { public: mutable std::mutex mut; std::stack<T> st; std::condition_variable cond; public: threadsafe_stack() = default; threadsafe_stack(const threadsafe_stack &s); threadsafe_stack(threadsafe_stack &&s); threadsafe_stack& operator=(const threadsafe_stack &s); threadsafe_stack& operator=(threadsafe_stack &&s); void push(const T &t); void push(T &&t); bool try_pop(T &t); std::shared_ptr<T> try_pop(); void wait_and_pop(T &t); std::shared_ptr<T> wait_and_pop(); typename std::stack<T>::size_type size() const; bool empty() const; }; template <typename T> threadsafe_stack<T>::threadsafe_stack(const threadsafe_stack &s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); st = s.st; } template <typename T> threadsafe_stack<T>::threadsafe_stack(threadsafe_stack &&s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); st = std::move(s.st); } template <typename T> threadsafe_stack<T>& threadsafe_stack<T>::operator=(const threadsafe_stack &s) { if (this == &s) return *this; std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); s = s.st; return *this; } template <typename T> threadsafe_stack<T>& threadsafe_stack<T>::operator=(threadsafe_stack &&s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); s = std::move(s.st); } template <typename T> void threadsafe_stack<T>::push(const T &t) { std::lock_guard<std::mutex> lock(mut); st.push(t); cond.notify_one(); } template <typename T> void threadsafe_stack<T>::push(T &&t) { std::lock_guard<std::mutex> lock(mut); st.push(std::move(t)); cond.notify_one(); } template <typename T> bool threadsafe_stack<T>::try_pop(T &t) { std::lock_guard<std::mutex> lock(mut); if (st.empty()) return false; t = st.top(); st.pop(); return true; } template <typename T> std::shared_ptr<T> threadsafe_stack<T>::try_pop() { std::lock_guard<std::mutex> lock(mut); if (st.empty()) return std::shared_ptr<T>(); std::shared_ptr<T> result(new T{st.top}); st.pop(); return result; } template <typename T> void threadsafe_stack<T>::wait_and_pop(T &t) { std::unique_lock<std::mutex> lock(mut); cond.wait(lock, [this]{ return !st.empty(); }); t = st.top(); st.pop(); } template <typename T> std::shared_ptr<T> threadsafe_stack<T>::wait_and_pop() { std::unique_lock<std::mutex> lock(mut); cond.wait(lock, [this]{ return !st.empty(); }); std::shared_ptr<T> result(new T{ st.top }); st.pop(); return result; } template <typename T> typename std::stack<T>::size_type threadsafe_stack<T>::size() const { std::lock_guard<std::mutex> lock(mut); return st.size(); } template <typename T> bool threadsafe_stack<T>::empty() const { std::lock_guard<std::mutex> lock(mut); return st.empty(); } #endif

线程安全堆栈互斥在忙时被破坏 我一直在学习C++标准库多线程的一段时间,作为一个练习,我想使用互斥阻塞和条件变量来做一个线程安全的堆栈。这是我上的课: #ifndef THREADSAFE_STACK_H_ #define THREADSAFE_STACK_H_ #include <mutex> #include <condition_variable> #include <stack> #include <memory> template <typename T> class threadsafe_stack { public: mutable std::mutex mut; std::stack<T> st; std::condition_variable cond; public: threadsafe_stack() = default; threadsafe_stack(const threadsafe_stack &s); threadsafe_stack(threadsafe_stack &&s); threadsafe_stack& operator=(const threadsafe_stack &s); threadsafe_stack& operator=(threadsafe_stack &&s); void push(const T &t); void push(T &&t); bool try_pop(T &t); std::shared_ptr<T> try_pop(); void wait_and_pop(T &t); std::shared_ptr<T> wait_and_pop(); typename std::stack<T>::size_type size() const; bool empty() const; }; template <typename T> threadsafe_stack<T>::threadsafe_stack(const threadsafe_stack &s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); st = s.st; } template <typename T> threadsafe_stack<T>::threadsafe_stack(threadsafe_stack &&s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); st = std::move(s.st); } template <typename T> threadsafe_stack<T>& threadsafe_stack<T>::operator=(const threadsafe_stack &s) { if (this == &s) return *this; std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); s = s.st; return *this; } template <typename T> threadsafe_stack<T>& threadsafe_stack<T>::operator=(threadsafe_stack &&s) { std::lock(mut, s.mut); std::lock_guard<std::mutex> lock1(mut, std::adopt_lock); std::lock_guard<std::mutex> lock2(s.mut, std::adopt_lock); s = std::move(s.st); } template <typename T> void threadsafe_stack<T>::push(const T &t) { std::lock_guard<std::mutex> lock(mut); st.push(t); cond.notify_one(); } template <typename T> void threadsafe_stack<T>::push(T &&t) { std::lock_guard<std::mutex> lock(mut); st.push(std::move(t)); cond.notify_one(); } template <typename T> bool threadsafe_stack<T>::try_pop(T &t) { std::lock_guard<std::mutex> lock(mut); if (st.empty()) return false; t = st.top(); st.pop(); return true; } template <typename T> std::shared_ptr<T> threadsafe_stack<T>::try_pop() { std::lock_guard<std::mutex> lock(mut); if (st.empty()) return std::shared_ptr<T>(); std::shared_ptr<T> result(new T{st.top}); st.pop(); return result; } template <typename T> void threadsafe_stack<T>::wait_and_pop(T &t) { std::unique_lock<std::mutex> lock(mut); cond.wait(lock, [this]{ return !st.empty(); }); t = st.top(); st.pop(); } template <typename T> std::shared_ptr<T> threadsafe_stack<T>::wait_and_pop() { std::unique_lock<std::mutex> lock(mut); cond.wait(lock, [this]{ return !st.empty(); }); std::shared_ptr<T> result(new T{ st.top }); st.pop(); return result; } template <typename T> typename std::stack<T>::size_type threadsafe_stack<T>::size() const { std::lock_guard<std::mutex> lock(mut); return st.size(); } template <typename T> bool threadsafe_stack<T>::empty() const { std::lock_guard<std::mutex> lock(mut); return st.empty(); } #endif,c++,multithreading,thread-safety,stack,mutex,C++,Multithreading,Thread Safety,Stack,Mutex,第二行在我按下任意键或尝试关闭控制台后立即出现。伴随着额外的消息,我得到了一个错误(我猜是未处理的异常?),在我看来,在我退出程序时,似乎正在使用互斥锁,但它不应该被使用,因为条件变量wait应该在等待时解锁它。我不知道。发生这种情况是因为程序退出,这会破坏全局变量。如果要等待程序完成工作,则需要加入底部的处理器线程(而不是将其分离) 条件变量只能使另一个线程休眠,而不能使主线程休眠。如果唯一使用互斥锁的是单个进程,则应使用关键部分。MSDN:“…临界截面对象提供了一种更快、更有效的互斥机制”-

第二行在我按下任意键或尝试关闭控制台后立即出现。伴随着额外的消息,我得到了一个错误(我猜是未处理的异常?),在我看来,在我退出程序时,似乎正在使用互斥锁,但它不应该被使用,因为条件变量wait应该在等待时解锁它。我不知道。

发生这种情况是因为程序退出,这会破坏全局变量。如果要等待程序完成工作,则需要加入底部的
处理器
线程(而不是将其分离)


条件变量只能使另一个线程休眠,而不能使主线程休眠。

如果唯一使用互斥锁的是单个进程,则应使用
关键部分。MSDN:“…临界截面对象提供了一种更快、更有效的互斥机制”-只是sayinOh noes,它的速度非常快?据我所知,互斥在Windows上是作为critsec实现的。@pappy Golly。那么,如果我真的想要一个互斥锁“保护共享资源不被多个线程或进程同时访问”,std::该怎么办?@MickyDuncan:可能什么都没有。该标准没有说明进程间通信或同步。@Puppy好的,谢谢Puppy
#include <iostream>
#include <condition_variable>
#include <ctime>
#include <chrono>
#include <thread>
#include "threadsafe_stack.h"


threadsafe_stack<int> data_stack;
void process_data()
{
    while (true)
    {
        int val = 0;
        data_stack.wait_and_pop(val);
        std::cout << val << " ";
    }
}


int main()
{
    std::thread processor(process_data);
    processor.detach();

    int values[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for (int i = 0; i < 10; i++)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        data_stack.push(values[i]);
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    system("pause");
    return 0;
}
1 2 3 4 5 6 7 8 9 10 Press any key to continue . . .
f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c(40): mutex destroyed while busy