在下面的示例中,我不了解ready
的目的。在此示例中,使用或不使用ready
有什么区别?
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id (int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
// ...
std::cout << "thread " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_id,i);
std::cout << "10 threads ready to race...\n";
go(); // go!
for (auto& th : threads) th.join();
return 0;
}
答案 0 :(得分:6)
原因是f1_macro_manual_2: 0.8535353535353535
可以在进行cv.wait(lck);
调用之前返回 ,这是由于“虚假唤醒”引起的。您可以查看Spurious wakeups explanation sounds like a bug that just isn't worth fixing, is that right?,了解有关原因的更多信息。
因此,等待/通知线程使用一个附加的谓词(在这种情况下为notify_all
)来指示是否已发出条件信号或该条件是否由于虚假唤醒而唤醒。
答案 1 :(得分:-1)
当它不是it("should catch the error", fakeAsync(() => {
spyOn(service, "loadObject").and.returnValue(Promise.reject("test error"));
spyOn(logService, "error"); // Might need to mock this method too
load();
// One of these
// flushMicroTasks();
// tick();
expect(logService.error).toHaveBeenCalledWith("test error");
}));
(ready
为假)时,您将阻塞一个或多个线程,直到您将它们中的一个/全部调用并让它们完成工作为止。但是,当ready
为true时,将不会阻塞任何线程。这很重要,因为如果没有ready
标志,您可能会阻塞应该执行的线程,因此将没有任何信息让它再次运行(当您阻塞线程时,您必须通知它,否则它将永远等待)< / p>