Nie mogę uzyskać niezawodnie działającego kodu w prostej aplikacji konsoli VS2012, składającej się z producenta i konsumenta, który używa zmiennej warunkowej C++ 11. Jestem zmierzające do produkcji małego niezawodnego programu (do wykorzystania jako podstawa do bardziej kompleksowego programu), który używa 3 argumentu wait_for metody lub być może metodą wait_until z kodem mam zebrane na tych stronach:Używanie zmiennej warunkowej C++ 11 w VS2012
condition_variable: wait_for , wait_until
Chciałbym użyć 3 argumentu wait_for z predykatem jak poniżej, z wyjątkiem tego, że będzie potrzebował użyć zmiennej członka klasy, aby być najbardziej użytecznym dla mnie później. Otrzymuję komunikat "Lokalizacja zapisu naruszenia zasad 0x_ _" lub "Nieprawidłowy parametr został przekazany do usługi lub funkcji" jako błędy po zaledwie około minucie uruchomienia.
Czy steady_clock i 2 argument wait_until będą wystarczające do zastąpienia 3 argument wait_for? Próbowałem tego również bez powodzenia.
Czy ktoś może pokazać, jak uzyskać poniższy kod, aby działał przez czas nieokreślony, bez błędów i dziwnych zachowań w przypadku zmiany czasu zegarowego z czasu letniego lub z synchronizacji czasu w Internecie?
Łącze do wiarygodnego kodu przykładowego może być równie pomocne.
// ConditionVariable.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
#include <atomic>
#define TEST1
std::atomic<int>
//int
qcount = 0; //= ATOMIC_VAR_INIT(0);
int _tmain(int argc, _TCHAR* argv[])
{
std::queue<int> produced_nums;
std::mutex m;
std::condition_variable cond_var;
bool notified = false;
unsigned int count = 0;
std::thread producer([&]() {
int i = 0;
while (1) {
std::this_thread::sleep_for(std::chrono::microseconds(1500));
std::unique_lock<std::mutex> lock(m);
produced_nums.push(i);
notified = true;
qcount = produced_nums.size();
cond_var.notify_one();
i++;
}
cond_var.notify_one();
});
std::thread consumer([&]() {
std::unique_lock<std::mutex> lock(m);
while (1) {
#ifdef TEST1
// Version 1
if (cond_var.wait_for(
lock,
std::chrono::microseconds(1000),
[&]()->bool { return qcount != 0; }))
{
if ((count++ % 1000) == 0)
std::cout << "consuming " << produced_nums.front () << '\n';
produced_nums.pop();
qcount = produced_nums.size();
notified = false;
}
#else
// Version 2
std::chrono::steady_clock::time_point timeout1 =
std::chrono::steady_clock::now() +
//std::chrono::system_clock::now() +
std::chrono::milliseconds(1);
while (qcount == 0)//(!notified)
{
if (cond_var.wait_until(lock, timeout1) == std::cv_status::timeout)
break;
}
if (qcount > 0)
{
if ((count++ % 1000) == 0)
std::cout << "consuming " << produced_nums.front() << '\n';
produced_nums.pop();
qcount = produced_nums.size();
notified = false;
}
#endif
}
});
while (1);
return 0;
}
Program Visual Studio Desktop Express miał jedną ważną aktualizację, którą zainstalował, a usługa Windows Update nie zawiera innych ważnych aktualizacji. Używam 32-bitowego systemu Windows 7.
Twój kod nie używa 'wait_for' lub' wait_until' i stąd nie rozwiąże problemu PO za. –