gpt4 book ai didi

c++ - 带有可变参数模板的 std::lock_guard

转载 作者:行者123 更新时间:2023-11-28 01:23:32 24 4
gpt4 key购买 nike

[无需点击链接即可理解问题]。

我在this answer中结合了单例模式的实现, 连同 this other answer 的同步文件写入.

然后我想看看SynchronizedFile的接口(interface)是不是可以提供可变参数模板 write方法,但我不知道如何将其与 std::lock_guard 正确结合.

下面是一个不工作的例子。在这种情况下它不起作用,因为(我认为)两个线程设法将内容泵入缓冲区 i_buf以非同步方式,导致乱码 LOGFILE.txt .

如果我把 std::lock_guardwrite 的通用模板内那么程序就不会停止。

#include <iostream>
#include <mutex>
#include <sstream>
#include <fstream>
#include <string>
#include <memory>
#include <thread>

static const int N_LOOP_LENGTH{10};

// This class manages a log file and provides write method(s)
// that allow passing a variable number of parameters of different
// types to be written to the file in a line and separated by commas.
class SynchronizedFile {
public:
static SynchronizedFile& getInstance()
{
static SynchronizedFile instance;
return instance;
}

private:
std::ostringstream i_buf;
std::ofstream i_fout;
std::mutex _writerMutex;

SynchronizedFile () {
i_fout.open("LOGFILE.txt", std::ofstream::out);
}

public:
SynchronizedFile(SynchronizedFile const&) = delete;
void operator=(SynchronizedFile const&) = delete;

template<typename First, typename... Rest>
void write(First param1, Rest...param)
{
i_buf << param1 << ", ";
write(param...);
}

void write()
{
std::lock_guard<std::mutex> lock(_writerMutex);
i_fout << i_buf.str() << std::endl;
i_buf.str("");
i_buf.clear();
}
};

// This is just some class that is using the SynchronizedFile class
// to write stuff to the log file.
class Writer {
public:
Writer (SynchronizedFile& sf, const std::string& prefix)
: syncedFile(sf), prefix(prefix) {}

void someFunctionThatWritesToFile () {
syncedFile.write(prefix, "AAAAA", 4343, "BBBBB", 0.2345435, "GGGGGG");
}
private:
SynchronizedFile& syncedFile;
std::string prefix;
};

void thread_method()
{
SynchronizedFile &my_file1 = SynchronizedFile::getInstance();
Writer writer1(my_file1, "Writer 1:");
for (int i = 0; i < N_LOOP_LENGTH; ++ i)
writer1.someFunctionThatWritesToFile();
}

int main()
{
std::thread t(thread_method);

SynchronizedFile &my_file2 = SynchronizedFile::getInstance();
Writer writer2(my_file2, "Writer 2:");
for (int i = 0; i < N_LOOP_LENGTH; ++i)
writer2.someFunctionThatWritesToFile();

t.join();
std::cout << "Done" << std::endl;
return 0;
}

我怎样才能成功地将这三个想法结合起来?

最佳答案

程序死锁是因为 write 在持有锁的同时递归调用自身。

要么使用 std::recursive_mutex 或在写完数据后但调用 write 之前释放锁。E:解锁不行,我没有想通...

E:或者锁定一次并推迟到另一个私有(private)方法来进行写入。

template<typename... Args>
void write(Args&&... args)
{
std::unique_lock<std::mutex> lock(_writerMutex);
_write(std::forward<Args>(args)...);
}

template<typename First, typename... Rest>
void _write(First&& param1, Rest&&... param) // private method
{
i_buf << std::forward<First>(param1) << ", ";
_write(std::forward<Rest>(param)...);
}

void _write()
{
i_fout << i_buf.str() << std::endl;
i_buf.clear();
}

关于c++ - 带有可变参数模板的 std::lock_guard,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55012923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com