Цель Asyncquery состоит в том, чтобы принять новые сообщения WSTRING как можно быстрее и «потреблять» их, отправив их на управляемую функцию (которая может быть медленной, потому что это происходит в потоке пользовательского интерфейса).
у меня есть следующая реализация, которая блокирует (тесты не закончатся), и я не понимаю, почему и как это исправить. < /p>
Кроме того, я не уверен, что Лучшая реализация, я подумал о кольцевом буфере с двумя std :: queue чередуются, поэтому, пока 1 питается, 2 потребляются, избегая блоков, но я все еще Нужна переменная условия и дождитесь случая, когда отмечается потребление. /> Delcarations: < /p>
#pragma once
#include
#include
typedef void(__stdcall* MessageChangedCallback)(const wchar_t* string);
class __declspec(dllexport) AsyncQuery
{
protected:
mutable std::mutex _mtx;
std::condition_variable _cv;
bool _run{ true };
std::queue _messages{};
MessageChangedCallback _log{};
int _count{};
std::thread _threadCall;
public:
AsyncQuery(MessageChangedCallback fn);
~AsyncQuery();
void Add(std::wstring msg);
void CallRunner();
int Count();
};
< /code>
Определения: < /p>
#include "pch.h"
#include "AsyncQuery.h"
AsyncQuery::AsyncQuery(MessageChangedCallback fn)
: _log(fn), _threadCall([&] { CallRunner(); })
{
}
AsyncQuery::~AsyncQuery()
{
_run = false;
_threadCall.join();
}
void AsyncQuery::Add(std::wstring msg)
{
std::lock_guard addLock(_mtx);
_messages.push(msg);
_cv.notify_one();
}
void AsyncQuery::CallRunner()
{
while (_run)
{
std::unique_lock readPopLock(_mtx);
_cv.wait(readPopLock, [this] { return !_messages.empty(); });
auto msg = _messages.front();
_messages.pop();
readPopLock.unlock();
_log(msg.c_str());
_count++;
}
}
int AsyncQuery::Count()
{
return _count;
}
< /code>
tests: < /p>
static MessageChangedCallback log = [](const wchar_t* z)
{
Logger::WriteMessage(z);
};
static MessageChangedCallback logDelay = [](const wchar_t* z)
{
Sleep(10);
Logger::WriteMessage(z);
};
TEST_CLASS(AsyncQueryTests)
{
public:
TEST_METHOD(AddTest)
{
AsyncQuery sut(log);
for (int i = 0; i < 10; ++i)
{
std::wstringstream wstr{};
wstr
Подробнее здесь: https://stackoverflow.com/questions/794 ... es-instead
У меня есть тупик? Стоит ли вместо этого использовать кольцевой буфер с очередями? ⇐ C++
Программы на C++. Форум разработчиков
1740236835
Anonymous
Цель Asyncquery состоит в том, чтобы принять новые сообщения WSTRING как можно быстрее и «потреблять» их, отправив их на управляемую функцию (которая может быть медленной, потому что это происходит в потоке пользовательского интерфейса).
у меня есть следующая реализация, которая блокирует (тесты не закончатся), и я не понимаю, почему и как это исправить. < /p>
Кроме того, я не уверен, что Лучшая реализация, я подумал о кольцевом буфере с двумя std :: queue чередуются, поэтому, пока 1 питается, 2 потребляются, избегая блоков, но я все еще Нужна переменная условия и дождитесь случая, когда отмечается потребление. /> Delcarations: < /p>
#pragma once
#include
#include
typedef void(__stdcall* MessageChangedCallback)(const wchar_t* string);
class __declspec(dllexport) AsyncQuery
{
protected:
mutable std::mutex _mtx;
std::condition_variable _cv;
bool _run{ true };
std::queue _messages{};
MessageChangedCallback _log{};
int _count{};
std::thread _threadCall;
public:
AsyncQuery(MessageChangedCallback fn);
~AsyncQuery();
void Add(std::wstring msg);
void CallRunner();
int Count();
};
< /code>
Определения: < /p>
#include "pch.h"
#include "AsyncQuery.h"
AsyncQuery::AsyncQuery(MessageChangedCallback fn)
: _log(fn), _threadCall([&] { CallRunner(); })
{
}
AsyncQuery::~AsyncQuery()
{
_run = false;
_threadCall.join();
}
void AsyncQuery::Add(std::wstring msg)
{
std::lock_guard addLock(_mtx);
_messages.push(msg);
_cv.notify_one();
}
void AsyncQuery::CallRunner()
{
while (_run)
{
std::unique_lock readPopLock(_mtx);
_cv.wait(readPopLock, [this] { return !_messages.empty(); });
auto msg = _messages.front();
_messages.pop();
readPopLock.unlock();
_log(msg.c_str());
_count++;
}
}
int AsyncQuery::Count()
{
return _count;
}
< /code>
tests: < /p>
static MessageChangedCallback log = [](const wchar_t* z)
{
Logger::WriteMessage(z);
};
static MessageChangedCallback logDelay = [](const wchar_t* z)
{
Sleep(10);
Logger::WriteMessage(z);
};
TEST_CLASS(AsyncQueryTests)
{
public:
TEST_METHOD(AddTest)
{
AsyncQuery sut(log);
for (int i = 0; i < 10; ++i)
{
std::wstringstream wstr{};
wstr
Подробнее здесь: [url]https://stackoverflow.com/questions/79459744/do-i-have-deadlock-should-i-use-a-ring-buffer-of-queues-instead[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия