下面的代码不会阻塞线程,它会进入无限循环并继续打印
等待...
等待...
我的想法是,线程应该在 max() 时间上阻塞,当它设置为 now() 时,它应该解除线程的阻塞并执行业务。有什么想法吗?我用的是VS2013
#include "stdafx.h"
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
std::condition_variable condVar;
std::mutex mut;
bool pred = false;
auto dueAt = std::chrono::steady_clock::time_point::max();
void threadFunc()
{
for (;;)
{
std::unique_lock<std::mutex> lock(mut);
dueAt = std::chrono::steady_clock::time_point::max();
if (condVar.wait_until(lock, dueAt, [](){ return pred; }))
{
std::cout << "Ready..." << std::endl;
pred = false;
dueAt = std::chrono::steady_clock::time_point::max();
}
else
{
std::cout << "Waiting..." << std::endl;
}
}
}
void notifierThread()
{
for (int i = 0; i < 5; i++)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
{
std::lock_guard<std::mutex> lock(mut);
dueAt = std::chrono::steady_clock::now();
pred = true;
std::cout << " Signalling..." << std::endl;
}
condVar.notify_one();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
std::thread t1(threadFunc);
std::thread t2(notifierThread);
t1.join();
t2.join();
return 0;
}
您的编译器很旧并且有错误?
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
std::condition_variable condVar;
std::mutex mut;
bool pred = false;
bool shutdown = false;
int result = 0;
void threadFunc()
{
for (;;)
{
std::unique_lock<std::mutex> lock(mut);
condVar.wait(lock, [](){ return pred || shutdown; });
if (shutdown) {
std::cout << "Shutdown!" << std::endl;
break;
}
std::cout << "Ready... #" << result << std::endl;
pred = false;
++result;
}
}
void notifierThread()
{
for (int i = 0; i < 5; i++)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
std::lock_guard<std::mutex> lock(mut);
pred = true;
std::cout << " Signalling... #" << i << std::endl;
}
condVar.notify_one();
}
}
int main()
{
std::thread t1(threadFunc);
std::thread t2(notifierThread);
t2.join();
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> l(mut);
if (result == 5)
{
std::cout << " Signalling Shutdown!" << std::endl;
shutdown = true;
break;
}
}
condVar.notify_one();
t1.join();
return 0;
}
这是程序的完整终止版本,不使用
dueAt
。
在
dueAt
时操纵 .wait_until
应该不会有任何作用(除非由于竞争条件而导致 UB,你用锁避免了这种情况)。 您的 C++ std
实现似乎有一个错误。
您到底想做什么还不清楚,所以我将您的代码转换为(可能)停止的代码。
实际上,您不能假设以这种方式发送 5 个信号会导致 5 个接收,因为
sleep(100 ms)
不能保证为读取器线程提供读取。 更合适的程序会发送一个计数器:
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
std::condition_variable condVar;
std::mutex mut;
int counter = 0;
bool shutdown = false;
int consumed = 0;
void threadFunc()
{
for (;;)
{
std::unique_lock<std::mutex> lock(mut);
auto old_count = counter;
condVar.wait(lock, [old_count](){ return (counter != old_count) || shutdown; });
if (shutdown) {
std::cout << "Shutdown!" << std::endl;
break;
}
std::cout << "Ready... #" << old_count << ".." << counter << std::endl;
consumed = counter;
}
}
void notifierThread()
{
std::this_thread::sleep_for(std::chrono::milliseconds(250));
for (int i = 0; i < 5; i++)
{
if (i%2)
std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
std::lock_guard<std::mutex> lock(mut);
++counter;
std::cout << " Signalling... #" << i << " with count " << counter << std::endl;
}
condVar.notify_one();
}
}
int main()
{
std::thread t1(threadFunc);
std::thread t2(notifierThread);
t2.join();
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> l(mut);
if (consumed == 5)
{
std::cout << " Signalling Shutdown!" << std::endl;
shutdown = true;
break;
}
}
condVar.notify_one();
t1.join();
return 0;
}
这里我让生产者变得飘忽不定,有时快有时慢。 然而,消费者可以一次处理超过 1 个信号。