如您所知,应该在循环中调用条件变量以避免虚假唤醒.像这样:
while (not condition)
condvar.wait();
Run Code Online (Sandbox Code Playgroud)
如果另一个线程想要唤醒等待线程,则必须将condition标志设置为true.例如:
condition = true;
condvar.notify_one();
Run Code Online (Sandbox Code Playgroud)
我想知道,这种情况是否有可能阻止条件变量:
1)等待线程检查条件标志,发现它等于FALSE,因此,它将进入condvar.wait()例程.
2)但就在此之前(但是在条件标志检查之后)等待线程被内核抢占(例如,因为时隙到期).
3)此时,另一个线程想要通知等待线程有关条件.它将条件标志设置为TRUE并调用condvar.notify_one();
4)当内核调度程序再次运行第一个线程时,它进入condvar.wait()例行程序,但通知已经丢失.
因此,等待线程无法退出condvar.wait(),尽管条件标志设置为TRUE,因为不再有唤醒通知.
可能吗?
让我们假设,我有一些序列,例如Fibonacci数,定义为模板:
template <unsigned int N> struct Fibonacci { unsigned int value = /*...*/; };
Run Code Online (Sandbox Code Playgroud)
我需要的是获得constexpr数组与该序列的前N个元素.我可以使用variadic模板来做到这一点:
template <unsigned int ... Numbers>
struct FibArray
{
static constexpr array<unsigned int, sizeof...(Numbers)> value = { Fibonacci<Numbers>::value... };
};
// and then:
const auto fib_array = FibArray<1, 2, 3, 4, 5, 6, 7>::value;
Run Code Online (Sandbox Code Playgroud)
是否可以避免手动枚举索引,并使用一些必需的值来获取相同的数组?像这样的东西:
const array<unsigned, 7> fib_array = GetFirstNFibValues<7>::value;
Run Code Online (Sandbox Code Playgroud) 我们假设我有几个模板函数,例如:
template <int I> void f();
template <int I> void g();
template <int I> void h();
Run Code Online (Sandbox Code Playgroud)
如何为模板参数序列调用任何这些函数的序列?
换句话说,我需要这样的行为:
{some template magic}<1, 5>(f); // This is pseudocode, I don't need exactly this format of calling.
Run Code Online (Sandbox Code Playgroud)
展开:
f<1>();
f<2>();
f<3>();
f<4>();
f<5>();
Run Code Online (Sandbox Code Playgroud)
而且我需要使用相同的方法来处理我的每个函数(不仅是f,还有g和h),而不需要为每个函数编写大的笨拙结构.
我可以使用C++ 11,甚至已经在最新开发的gcc版本C++ 1y/C++ 14功能(http://gcc.gnu.org/projects/cxx1y.html)中实现,例如多态lambda.
在此示例中将唤醒多少个等待线程:
第一个帖子:
void wakeUp2Threads()
{
std::unique_lock<std::mutex> lock(condvar_mutex);
condvar.notify_one();
condvar.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
第二线程:
{
std::unique_lock<std::mutex> lock(condvar_mutex);
condvar.wait(lock); <- 2nd thread has entered here before 1st thread entered wakeUp2Threads.
}
Run Code Online (Sandbox Code Playgroud)
第3个帖子(与第2 个帖子相同):
{
std::unique_lock<std::mutex> lock(condvar_mutex);
condvar.wait(lock); <- 3rd thread has entered here before 1st thread entered wakeUp2Threads.
}
Run Code Online (Sandbox Code Playgroud)
有没有保证在这个例子中两个通知都会被传递到不同的线程,而不是多次传递给同一个线程?
即notify_one()是什么意思:
1) notify one thread, no matter has it been already notified (but has not been woken up yet), or not. (* see note)
or
2) notify one thread, but …Run Code Online (Sandbox Code Playgroud)