Устранена гонка за данными при инициализации очереди логгера
This commit is contained in:
parent
966e729bf8
commit
86d129e335
4
Makefile
4
Makefile
@ -10,8 +10,8 @@ OS = linux
|
|||||||
|
|
||||||
# C++ compier
|
# C++ compier
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -MMD -c -g -Og -Wall -Werror -std=c++11 -Iinclude -Isrc/asm/include
|
CXXFLAGS = -MMD -c -g -Og -Wall -Werror -std=c++11 -Iinclude -Isrc/asm/include #-fsanitize=thread -fPIE
|
||||||
LDFLAGS = -lgtest
|
LDFLAGS = -lgtest #-ltsan -pie
|
||||||
|
|
||||||
# Archiver
|
# Archiver
|
||||||
AR = ar
|
AR = ar
|
||||||
|
|||||||
@ -6,14 +6,16 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
class log_queue
|
class log_queue
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::thread _worker;
|
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
std::condition_variable _cond;
|
std::condition_variable _cond;
|
||||||
std::queue<std::function<void()>> _queue;
|
std::queue<std::function<void()>> _queue;
|
||||||
|
std::atomic<bool> _working;
|
||||||
|
std::thread _worker;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void worker_func();
|
void worker_func();
|
||||||
|
|||||||
@ -19,16 +19,16 @@ private:
|
|||||||
public:
|
public:
|
||||||
logger();
|
logger();
|
||||||
|
|
||||||
void set_enabled(bool enabled)
|
void set_enabled(bool enabled);
|
||||||
{
|
|
||||||
_enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args> void log(const char* s, const Args&... args)
|
template<typename... Args> void log(const char* s, const Args&... args)
|
||||||
{
|
{
|
||||||
|
std::cout << "step 1" << std::endl;
|
||||||
if(_enabled)
|
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("");
|
_logLine.str("");
|
||||||
log_internal(s, args...);
|
log_internal(s, args...);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
#include "log_queue.h"
|
#include "log_queue.h"
|
||||||
#include <iostream>
|
#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()
|
log_queue::~log_queue()
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(_mutex);
|
||||||
|
_queue.push([]{});
|
||||||
|
_working = false;
|
||||||
|
_cond.notify_one();
|
||||||
|
lock.unlock();
|
||||||
_worker.join();
|
_worker.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,6 +23,10 @@ void log_queue::worker_func()
|
|||||||
_cond.wait(lock, [this] { return !_queue.empty(); });
|
_cond.wait(lock, [this] { return !_queue.empty(); });
|
||||||
std::function<void()> func = _queue.front();
|
std::function<void()> func = _queue.front();
|
||||||
_queue.pop();
|
_queue.pop();
|
||||||
|
|
||||||
|
if(_queue.empty() && !_working)
|
||||||
|
return;
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
func();
|
func();
|
||||||
|
|||||||
@ -8,6 +8,11 @@ logger::logger(): _enabled(true)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logger::set_enabled(bool enabled)
|
||||||
|
{
|
||||||
|
_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void logger::log_internal(const char *s)
|
void logger::log_internal(const char *s)
|
||||||
{
|
{
|
||||||
while (*s)
|
while (*s)
|
||||||
|
|||||||
@ -561,18 +561,38 @@ TEST(Ustring, replace_string)
|
|||||||
EXPECT_TRUE(str2 == "33 hello 33 world 33 more 33 and 33 more 33");
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
//::testing::InitGoogleTest(&argc, argv);
|
//::testing::InitGoogleTest(&argc, argv);
|
||||||
//return RUN_ALL_TESTS();
|
//return RUN_ALL_TESTS();
|
||||||
|
|
||||||
int one = 1;
|
const std::size_t threadsCount = 2;
|
||||||
double two = 2.5;
|
//int one = 1;
|
||||||
ulog.log("one: %, two: %", one, two);
|
//double two = 2.5;
|
||||||
ulog.log("Hello world!");
|
//ulog.log("one: %, two: %", one, two);
|
||||||
|
//ulog.log("Hello world!");
|
||||||
|
//ulog.log("some string: %", "qwe!");
|
||||||
|
|
||||||
int i = 0;
|
std::thread threads[threadsCount];
|
||||||
std::cin >> i;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user