std::atomic<T>两者std::condition_variable都有成员wait和notify_one功能。在某些应用程序中,程序员可以选择使用其中之一来实现同步目的。这些wait函数的目标之一是它们应与操作系统协调以最大程度地减少虚假唤醒。也就是说,操作系统应该避免唤醒wait-ing 线程,直到notify_one或notify_all被调用。
在我的机器上,sizeof(std::atomic<T>)issizeof(T)和sizeof(std::condition_variable)is 72。如果排除std::atomic<T>的T成员,则std::condition_variable保留 72 字节用于其同步目的,同时sizeof(std::atomic<T>)保留 0 字节。
我的问题:我应该期望std::condition_variables 和std::atomic<T>swait函数之间有不同的行为吗?例如,是否应该std::condition_variable减少虚假唤醒?
我们可以使用新的条件变量原语或windows事件来同步WinNT v6.x或更高版本中的线程.考虑以下两种方法,我们希望工作者在main中设置"go"的同时运行,否则它们都应该阻塞.
/*language C code*/
/*Windows Condition Variable*/
int go=0;
CONDITION_VARIABLE cv;
SRWLOCK lock;
void workers()
{
AcquireSRWLockShared(&lock);
if(go==0)
{
SleepConditionVariableSRW(&cv, &lock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
}
ReleaseSRWLockShared(&lock);
/*
Workers continue...
*/
}
void main()
{
int i;
InitializeConditionVariable(&cv);
InitializeSRWLock(&lock);
for(i=0;i<10;i++)
{
CreateThread(0, 0, workers, 0, 0, 0);
}
AcquireSRWLockExclusive(&lock);
go=1;
ReleaseSRWLockExclusive(&lock);
WakeAllConditionVariable(&cv);
}
Run Code Online (Sandbox Code Playgroud)
要么
/*language C code*/
/*Windows Event*/
HANDLE go;
void workers()
{
WaitForSingleObject(go, INFINITE);
/*
Workers continue...
*/
}
void main()
{
int i;
go=CreateEvent(0,1,0,0); /*No security descriptor, Manual …Run Code Online (Sandbox Code Playgroud) c windows multithreading condition-variable readerwriterlockslim
我有线程1执行以下代码:
unique_lock<mutex> ul(m);
while(condition == true)
cv.wait(ul);
Run Code Online (Sandbox Code Playgroud)
并且线程2执行此代码:
condition = false;
cv.notify_one();
Run Code Online (Sandbox Code Playgroud)
不幸的是我遇到了时间问题:
T1: condition checks true
T2: condition set to false
T2: cv.notify_one()
T1: cv.wait()
Run Code Online (Sandbox Code Playgroud)
线程1完全错过了通知,并在wait()时保持阻塞状态.我尝试使用wait()版本,它接受一个谓词,但结果基本相同.也就是说,谓词的主体执行检查,但在它返回之前,条件的值被改变并且发送通知.然后谓词返回.
我怎样才能解决这个问题?
各种平台都允许虚假wakup.为了解决这个问题,我们在下面写出循环机制:
while(ContinueWaiting())
cv.wait(lock); // cv is a `std::conditional_variable` object
Run Code Online (Sandbox Code Playgroud)
同样的事情是可以理解的conditional_variable::wait_until().
但请看下面的例子:
const auto duration = Returns_10_seconds();
while(!Predicate())
cv.wait_for(lock, duration);
Run Code Online (Sandbox Code Playgroud)
想象一下,虚假的唤醒发生在1秒钟.超时尚未达成.
它会再等10秒吗?这将导致无限循环,我相信不应该发生.从源代码,内部wait_for()调用wait_until().
我想了解,如何wait_for()处理虚假的唤醒?
我正在尝试等待特定的条件,我想了解如何最好地完成此操作的建议。我有一个如下所示的结构(简化):
type view struct {
timeFrameReached bool
Rows []*sitRow
}
Run Code Online (Sandbox Code Playgroud)
在 goroutine 中,我正在更新一个文件,该文件被读入view变量中。行数增加,timeFrameReached最终将是true。
在其他地方,我想等待以下条件成立:
view.timeFrameReached == true || len(view.Rows) >= numRows
Run Code Online (Sandbox Code Playgroud)
我正在尝试学习通道以及 Go 的条件变量如何工作,我想知道这里最好的解决方案是什么。理论上,我可以做这样的小事:
for {
view = getView()
if view.timeFrameReached == true || len(view.Rows) >= numRows {
break
}
}
Run Code Online (Sandbox Code Playgroud)
但这显然是一个幼稚的解决方案。的值numRows来自 HTTP 请求,因此条件方法似乎具有挑战性。Goroutine 不知道何时广播条件,因为它不知道它正在查找的行数。
为简单起见,我们假设我们只有一个条件变量来匹配由布尔值反映的单个条件.
1)为什么std::condition_variable::wait(...)在发送"通知"后才重新锁定互斥锁?
2)看到"1)"中的行为,这是否意味着当你这样做std::condition_variable::notify_all时只会使所有等待的线程被解锁/唤醒...但是按顺序而不是一次完成所有?如果是这样,可以做些什么来一次完成这一切?
3)如果我只关心线程睡眠直到满足条件并且不关心任何互斥锁获取,我该怎么办?是否有替代方案或当前的std::condition_variable::wait(...)方法是否应该被攻击?
如果要使用"hackery",这个函数是否可以解除条件中所有等待线程的阻塞,并且可以从任何(每个线程)线程调用它:
//declared somehwere and modified before sending "notify"(ies)
std::atomic<bool> global_shared_condition_atomic_bool;
//the single(for simplicity in our case) condition variable matched with the above boolean result
std::condition_variable global_shared_condition_variable;
static void MyClass:wait()
{
std::mutex mutex;
std::unique_lock<std::mutex> lock(mutex);
while (!global_shared_condition_atomic_bool) global_shared_condition_variable.wait(lock);
}
Run Code Online (Sandbox Code Playgroud)
它会被随机的"等待"线程调用,如下所示:
void random_thread_run()
{
while(someLoopControlValue)
{
//random code...
MyClass:wait(); //wait for whatever condition the class+method is for.
//more random code...
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
门类
#ifndef Gate_Header
#define Gate_Header …Run Code Online (Sandbox Code Playgroud) 哪些主要操作系统/平台实现了等待变形?
当我注意到没有明确的最佳实践时,就出现了这个问题,即是否应该在互斥锁锁定的情况下向条件变量发出信号。一个典型的建议是在持有锁的同时发出信号,除非分析显示解锁带来的显着性能改进开销(通过删除额外的上下文切换)。
IIUC,在发信号时持有锁的唯一缺点是额外的两个上下文切换;优点是出现错误的风险较低,并且更容易实现实时可预测性。
因此,似乎如果实现了等待变形,那么在发信号时持有锁的做法会更好。
language-agnostic linux multithreading window condition-variable
请考虑以下codesnippet:
#include <iostream>
#include <condition_variable>
#include <chrono>
#include <mutex>
int main () {
std::mutex y;
std::condition_variable x;
std::unique_lock<std::mutex>lock{y};
int i = 0;
auto increment = [&] {++i; return false;};
using namespace std::chrono_literals;
//lock 5s if increment returns false
//let's see how often was increment called?
x.wait_for(lock, 5s, increment);
std::cout << i << std::endl;
//compare this with a simple loop:
//how often can my system call increment in 5s?
auto const end = std::chrono::system_clock::now() + 5s;
i = 0;
while (std::chrono::system_clock::now() …Run Code Online (Sandbox Code Playgroud) 我正在使用在 ARM(而不是英特尔处理器)上运行的代码。从http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/运行 c++11 代码示例(代码 A)来测试 wait_for() 机制。这不起作用 - 看起来 wait_for() 不等待。在英特尔工作得很好。经过一些研究并直接使用 pthread 库并设置 MONOTONIC_CLOCK 定义,解决了问题(代码 B)。(在ARM上运行不是问题)
我的问题是:如何强制 C++11 API wait_for() 与 MONOTONIC_CLOCK 一起使用?
实际上我想保留“CODE A”,但需要 MONOTONIC_CLOCK 的支持或设置。谢谢
// condition_variable::wait_for example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
std::condition_variable cv;
int value;
void read_value() {
std::cin >> value;
cv.notify_one();
}
int main ()
{
std::cout << "Please, enter an integer (I'll be printing …Run Code Online (Sandbox Code Playgroud) 我的问题是通过使用std::promise通知关联吗? std::futurestd::condition_variable
我搜索的源代码std::promise并找到了该网站。但我没有看到std::promise已经std::condition_variable在其成员的数据。