在下面的(伪)代码中,cond无论出于何种原因,它可能会在不应该唤醒的情况下唤醒.所以我在那里放了一个while循环.当它确实唤醒时,它仍将消耗锁定,因此可以保证out()只有一个线程正在执行其工作.
但是,如果虽然有一个虚假的唤醒out(),同时in()发出信号out(),但是在那个时刻out()由于虚假的唤醒已经被锁定,会发生什么.那么如果cond向锁定线程发出信号会发生什么?
in()
inLock.lock()
isEmpty = false
cond.signal()
inLock.unlock()
out()
outLock.lock()
while isEmpty
cond.wait(outLock)
isEmpty = true
outLock.unlock()
Run Code Online (Sandbox Code Playgroud)
注意
那么,是100%的安全,我知道我可以使用一个互斥两个in()和out(),但我使用的数据结构是100%安全的,当输入和输出发生在同一时间; 它是一种队列.而且我认为在填充一些新数据时阻止从队列读出的任何内容都是一种性能折衷,反之亦然.
我确实考虑过使用信号量,但问题是,无论出于何种原因,许多C和C++库都没有实现信号量.
我正在编写 C++ ThreadPool 植入并在我的工作人员的主函数中使用 pthread_cond_wait。我想知道从发出条件变量信号到等待它的线程/线程唤醒需要多长时间。你知道我如何估计/计算这个时间吗?
非常感谢。
我指的是这段特定的代码:
该代码基本上具有三个线程1.与服务器进行一些握手2.从XML文件加载数据。3.对从XML加载的数据进行处理。如我们所见,任务1不依赖于任何其他任务,但是任务3依赖于任务2。因此,这意味着任务1和任务2可以由不同的线程并行运行以提高应用程序的性能。因此,应用程序被构建为多线程的。
#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std::placeholders;
class Application
{
std::mutex m_mutex;
std::condition_variable m_condVar;
bool m_bDataLoaded;
public:
Application()
{
m_bDataLoaded = false;
}
void loadData()
{
// Make This Thread sleep for 1 Second
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout<<"Loading Data from XML"<<std::endl;
// Lock The Data structure
std::lock_guard<std::mutex> guard(m_mutex);
// Set the flag to true, means data is loaded
m_bDataLoaded = true;
// Notify the condition variable
m_condVar.notify_one();
}
bool isDataLoaded()
{
return m_bDataLoaded;
} …Run Code Online (Sandbox Code Playgroud) 我试图了解在条件变量的情况下虚假唤醒与丢失唤醒之间的区别。以下是我试过的小块代码。我知道在这种情况下“消费者”可能会在没有任何通知的情况下醒来,因此等待需要检查谓词。
但是wait with predicate 如何解决“丢失唤醒”的问题呢?正如你在下面的代码中看到的;'wait' 没有被调用 5 秒,我原以为它会错过前几个通知;但有了 predate,它不会错过任何一个。这些通知是否已保存以备将来等待?
#include <iostream>
#include <deque>
#include <condition_variable>
#include <thread>
std::deque<int> q;
std::mutex m;
std::condition_variable cv;
void dump_q()
{
for (auto x: q) {
std::cout << x << std::endl;
}
}
void producer()
{
for(int i = 0; i < 10; i++) {
std::unique_lock<std::mutex> locker(m);
q.push_back(i);
std::cout << "produced: " << i << std::endl;
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
locker.unlock();
}
}
void consumer()
{
while (true) {
int data = 0;
std::this_thread::sleep_for(std::chrono::seconds(5)); // <- should …Run Code Online (Sandbox Code Playgroud) c++ multithreading synchronization condition-variable race-condition
在参考文档中std::condition_variable有这个例子:
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
// Wait until main() sends data
std::unique_lock lk(m);
cv.wait(lk, []{ return ready; });
// after the wait, we own the lock.
std::cout << "Worker thread is processing data\n";
data += " after processing";
// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completed\n"; …Run Code Online (Sandbox Code Playgroud) 关于这个: 如何使用条件变量
假设我们有许多执行此类代码的消费者线程(从引用的页面复制):
while (TRUE) {
s = pthread_mutex_lock(&mtx);
while (avail == 0) { /* Wait for something to consume */
s = pthread_cond_wait(&cond, &mtx);
}
while (avail > 0) { /* Consume all available units */
avail--;
}
s = pthread_mutex_unlock(&mtx);
}
Run Code Online (Sandbox Code Playgroud)
我假设这里的场景是:主线程调用pthread_cond_signal()来告诉消费者线程做一些工作.
据我所知 - 后续线程调用pthread_mutex_lock()然后调用pthread_cond_wait()(以原子方式解锁互斥锁).到目前为止,没有任何消费者线程声称使用互斥锁,它们都在pthread_cond_wait()上等待.
当主线程调用pthread_cond_signal()时,在联机帮助页之后,至少会唤醒一个线程.当它们中的任何一个从pthread_cond_wait()返回时,它会自动声明互斥锁.
所以我的问题是:现在关于提供的示例代码会发生什么?也就是说,失去互斥体竞赛的线程现在做了什么?
(AFAICT赢得互斥锁的线程,应该运行其余的代码并释放互斥锁.丢失的那个应该等待互斥锁 - 在第一个嵌套 while循环中的某个地方- 而胜利者持有它并且在它被释放之后在pthread_cond_wait()上开始阻塞,因为while (avail == 0)那时将满足.我是否正确?)
想象一下线程阻塞条件变量:
pthread_mutex_lock (mutex);
do_something ();
pthread_cond_wait(cond, mutex); // [1]
do_something_else ();
pthread_mutex_unlock (mutex);
Run Code Online (Sandbox Code Playgroud)
互斥锁已解锁,并且尝试锁定互斥锁的其他线程未被阻止:
pthread_mutex_lock (mutex);
do_some_work ();
pthread_cond_signal (cond);
pthread_mutex_unlock (mutex);
Run Code Online (Sandbox Code Playgroud)
同时还有另一个线程在等待获取关键部分的所有权:
pthread_mutex_lock (mutex); // [2]
do_some_random_work ();
pthread_mutex_unlock (mutex);
Run Code Online (Sandbox Code Playgroud)
现在,问题是:当调用pthread_cond_signal()时,是否保证pthread_cond_wait()[1]将在pthread_mutex_lock()[2]之前解除阻塞?
POSIX规范似乎没有说明这个案例.
由于某种原因,调用signal.notify_one()会阻止当前线程并且不会返回.我从来没有听说过这种行为,我不知道如何解决它.
{
std::lock_guard<std::mutex> lock(_mutex);
_exit = true; // _exit is a std::atomic<bool>
}
std::cout << "before" << std::endl;
_signal.notify_one();
std::cout << "after" << std::endl;
_thread.join();
Run Code Online (Sandbox Code Playgroud)
我正在使用Microsoft Visual C++ 2015,并且在销毁期间调用上面的代码.
我希望你能指出我正确的方向,非常感谢你的帮助!
c++ multithreading condition-variable poco-libraries visual-studio-2015
使用条件变量时,http://en.cppreference.com/w/cpp/thread/condition_variable描述了通知的线程的典型步骤:
- 获取std :: mutex(通常通过std :: lock_guard)
- 在锁定时执行修改
- 在std :: condition_variable上执行notify_one或notify_all(不需要保持锁定以进行通知)
对于下面显示的简单情况,主线程在修改它时是否需要锁定"停止"?虽然我理解在修改共享数据时锁定几乎总是一个好主意,但我不确定为什么在这种情况下它是必要的.
std::condition_variable cv;
std::mutex mutex;
bool stop = false;
void worker() {
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [] { return stop; })
}
// No lock (Why would this not work?)
void main() {
std::thread(worker);
std::this_thread::sleep_for(1s);
stop = true;
cv.notify_one();
}
// With lock: why is this neccesary?
void main() {
std::thread mythread(worker);
std::this_thread::sleep_for(1s);
{
std::unique_lock<std::mutex>(mutex);
stop = true;
}
cv.notify_one();
mythread.join();
}
Run Code Online (Sandbox Code Playgroud) 我目前正在研究std :: condition_variable。在while循环内使用std :: condition_variable :: wait()完全不依赖std :: condition_variable :: notify()是否正确?
每个std :: condition_variable :: wait()都应强制具有std :: condition_variable :: notify()吗?