Устранена гонка за данными при инициализации очереди логгера

This commit is contained in:
selim 2014-08-28 22:20:38 +04:00
parent 966e729bf8
commit 86d129e335
6 changed files with 51 additions and 15 deletions

View File

@ -10,8 +10,8 @@ OS = linux
# C++ compier
CXX = g++
CXXFLAGS = -MMD -c -g -Og -Wall -Werror -std=c++11 -Iinclude -Isrc/asm/include
LDFLAGS = -lgtest
CXXFLAGS = -MMD -c -g -Og -Wall -Werror -std=c++11 -Iinclude -Isrc/asm/include #-fsanitize=thread -fPIE
LDFLAGS = -lgtest #-ltsan -pie
# Archiver
AR = ar

View File

@ -6,14 +6,16 @@
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
class log_queue
{
private:
std::thread _worker;
std::mutex _mutex;
std::condition_variable _cond;
std::queue<std::function<void()>> _queue;
std::atomic<bool> _working;
std::thread _worker;
private:
void worker_func();

View File

@ -19,16 +19,16 @@ private:
public:
logger();
void set_enabled(bool enabled)
{
_enabled = enabled;
}
void set_enabled(bool enabled);
template<typename... Args> void log(const char* s, const Args&... args)
{
std::cout << "step 1" << std::endl;
if(_enabled)
{
_queue.add_log([this, s, &args...] {
std::cout << "step 2" << std::endl;
_queue.add_log([this, s, args...] {
std::cout << "step 3" << std::endl;
_logLine.str("");
log_internal(s, args...);
});

View File

@ -1,12 +1,17 @@
#include "log_queue.h"
#include <iostream>
log_queue::log_queue(): _worker(&log_queue::worker_func, this)
log_queue::log_queue(): _working(true), _worker(&log_queue::worker_func, this)
{
}
log_queue::~log_queue()
{
std::unique_lock<std::mutex> lock(_mutex);
_queue.push([]{});
_working = false;
_cond.notify_one();
lock.unlock();
_worker.join();
}
@ -18,6 +23,10 @@ void log_queue::worker_func()
_cond.wait(lock, [this] { return !_queue.empty(); });
std::function<void()> func = _queue.front();
_queue.pop();
if(_queue.empty() && !_working)
return;
lock.unlock();
func();

View File

@ -8,6 +8,11 @@ logger::logger(): _enabled(true)
{
}
void logger::set_enabled(bool enabled)
{
_enabled = enabled;
}
void logger::log_internal(const char *s)
{
while (*s)

View File

@ -561,18 +561,38 @@ TEST(Ustring, replace_string)
EXPECT_TRUE(str2 == "33 hello 33 world 33 more 33 and 33 more 33");
}
void func(std::size_t n)
{
for(std::size_t j = 0; j < 100; ++j)
{
ulog.log("thread %, line %", n, j);
}
std::cout << "end of thread " << n << std::endl;
}
int main(int argc, char **argv)
{
//::testing::InitGoogleTest(&argc, argv);
//return RUN_ALL_TESTS();
int one = 1;
double two = 2.5;
ulog.log("one: %, two: %", one, two);
ulog.log("Hello world!");
const std::size_t threadsCount = 2;
//int one = 1;
//double two = 2.5;
//ulog.log("one: %, two: %", one, two);
//ulog.log("Hello world!");
//ulog.log("some string: %", "qwe!");
int i = 0;
std::cin >> i;
std::thread threads[threadsCount];
for(std::size_t i = 0; i < threadsCount; ++i)
{
threads[i] = std::thread(func, i);
}
std::cout << "the end" << std::endl;
for(std::size_t i = 0; i < threadsCount; ++i)
threads[i].join();
return 0;
}