程序语言:C ++ 11
我使用管道线程模式处理数据。
一个线程生成数据。
一线程处理数据。
虽然没有数据要处理,但这是产生线程的最佳方法?
现在我用
std::this_thread::sleep_for(100ms);
答案 0 :(得分:6)
哪个是产生线程的最佳方法?
它是std::this_thread::yield
。
现在我使用
std::this_thread::sleep_for(100ms);
虽然睡眠确实会产生线程副作用,但这还不是全部。顾名思义,它会在给定时间内阻止线程。
但是,尚不清楚产量或睡眠在生产者/消费者案例(例如您所描述的案例)中如何有用。您可能应该做的是改为等待条件变量。
答案 1 :(得分:2)
介绍一个等待条件,您的使用者线程需要等待。 生产者生成数据后,它可以通知您的使用者线程,直到使用者等待。
答案 2 :(得分:0)
通过数据队列进行通信。如果需要,队列可以具有最大大小。
一个线程生成数据并将其推入队列。
另一个线程将数据弹出队列并进行处理。
当队列为空时,使用线程在队列中等待要推送的新数据。
当队列已满时,生产线程在队列中等待弹出数据。或者,您可以丢弃并替换队列中的等待数据。这取决于您的数据模型是什么样的(最新是重要的,还是有序的所有都是重要的)
简单队列:
template<class T>
struct threadsafe_queue {
T pop() {
auto l = lock();
cv.wait( l, [&]{ return !data.empty(); } );
T r = std::move(data.front());
data.pop_front();
return r;
}
void push( T&& t ) {
auto l = lock();
data.push_back( std::move(t) );
cv.notify_one();
}
void abandon() {
auto l = lock();
data = {};
}
private:
std::unique_lock<std::mutex> lock() { return std::unique_lock<std::mutex>(m); }
std::mutex m;
std::condition_variable cv;
std::deque<T> data;
};
对条目数有限制的人应该有第二个condition_variable来通知某人弹出,并且推送应查看您是否已达到限制。
支持“已满时覆盖”成为另一种选择。一个1元素的“最新”看起来像:
template<class T>
struct mono_threadsafe_queue {
// waits until we have data, then returns it.
T pop() {
auto l = lock();
cv_hasdata.wait( l, [&]{ return (bool)data; } );
T r = std::move(*data);
data = boost::none;
cv_hasroom.notify_one();
return r;
}
// waits for there to be room if there is none.
void push( T&& t ) {
auto l = lock();
cv_hasroom.wait( l, [&]{ return !(bool)data; } );
data = std::move(t);
cv_hasdata.notify_one();
}
void replace( T&& t ) {
auto l = lock();
data = std::move(t);
cv_hasdata.notify_one();
}
// replaces data if f returns true, or if there is no data
// imagine data with a timestamp, and we only want to replace it with
// newer data
template<class F>
void replace_if( T&& t, F&& f ) {
auto l = lock();
if (!data || !f(*data))
{
data = std::move(t);
cv_hasdata.notify_one();
}
}
void abandon() {
auto l = lock();
data = boost::none;
cv_hasroom.notify_one();
}
private:
std::unique_lock<std::mutex> lock() { return std::unique_lock<std::mutex>(m); }
std::mutex m;
std::condition_variable cv_hasdata;
std::condition_variable cv_hasroom;
boost::optional<T> data;
};