这是模板
#pragma once
#include <shared_mutex>
#include <memory>
#include <functional>
#include <optional>
#include <type_traits>
// 辅助类型特征
template<typename Container>
struct is_associative_container {
static constexpr bool value =
std::is_same_v<typename Container::value_type,
std::pair<const typename Container::key_type, typename Container::mapped_type>>;
};
template<typename Container>
constexpr bool is_associative_container_v = is_associative_container<Container>::value;
template<typename Container>
class ThreadSafeContainer {
public:
using value_type = typename Container::value_type;
using iterator = typename Container::iterator;
using const_iterator = typename Container::const_iterator;
// 对于关联容器,定义额外的类型
template<typename C = Container>
using key_type = typename std::enable_if<is_associative_container_v<C>, typename C::key_type>::type;
template<typename C = Container>
using mapped_type = typename std::enable_if<is_associative_container_v<C>, typename C::mapped_type>::type;
// 构造函数
ThreadSafeContainer() = default;
ThreadSafeContainer(const Container& container) : m_container(container) {}
ThreadSafeContainer(Container&& container) : m_container(std::move(container)) {}
// 写操作 - 使用独占锁
template<typename... Args>
void emplace(Args&&... args) {
std::lock_guard<std::shared_mutex> lock(m_mutex);
m_container.emplace(std::forward<Args>(args)...);
}
template<typename C = Container, typename... Args>
auto try_emplace(Args&&... args) ->
typename std::enable_if<is_associative_container_v<C>,
std::pair<iterator, bool>>::type {
std::lock_guard<std::shared_mutex> lock(m_mutex);
return m_container.try_emplace(std::forward<Args>(args)...);
}
void insert(const value_type& value) {
std::lock_guard<std::shared_mutex> lock(m_mutex);
m_container.insert(value);
}
void insert(value_type&& value) {
std::lock_guard<std::shared_mutex> lock(m_mutex);
m_container.insert(std::move(value));
}
// 对于关联容器的erase
template<typename C = Container, typename K = key_type<C>>
auto erase(const K& key) ->
typename std::enable_if<is_associative_container_v<C>, size_t>::type {
std::lock_guard<std::shared_mutex> lock(m_mutex);
return m_container.erase(key);
}
// 对于序列容器的erase
template<typename C = Container>
auto erase(iterator pos) ->
typename std::enable_if<!is_associative_container_v<C>, iterator>::type {
std::lock_guard<std::shared_mutex> lock(m_mutex);
return m_container.erase(pos);
}
void clear() {
std::lock_guard<std::shared_mutex> lock(m_mutex);
m_container.clear();
}
// 对于关联容器的find
template<typename C = Container, typename K = key_type<C>>
auto find(const K& key) const ->
typename std::enable_if<is_associative_container_v<C>,
std::optional<typename C::mapped_type>>::type {
std::shared_lock<std::shared_mutex> lock(m_mutex);
auto it = m_container.find(key);
if (it != m_container.end()) {
return it->second;
}
return std::nullopt;
}
// 对于序列容器的find
template<typename C = Container, typename T = value_type>
auto find(const T& value) const ->
typename std::enable_if<!is_associative_container_v<C>,
std::optional<iterator>>::type {
std::shared_lock<std::shared_mutex> lock(m_mutex);
auto it = std::find(m_container.begin(), m_container.end(), value);
if (it != m_container.end()) {
return it;
}
return std::nullopt;
}
template<typename C = Container, typename K = key_type<C>>
auto contains(const K& key) const ->
typename std::enable_if<is_associative_container_v<C>, bool>::type {
std::shared_lock<std::shared_mutex> lock(m_mutex);
return m_container.find(key) != m_container.end();
}
template<typename C = Container, typename T = value_type>
auto contains(const T& value) const ->
typename std::enable_if<!is_associative_container_v<C>, bool>::type {
std::shared_lock<std::shared_mutex> lock(m_mutex);
return std::find(m_container.begin(), m_container.end(), value) != m_container.end();
}
size_t size() const {
std::shared_lock<std::shared_mutex> lock(m_mutex);
return m_container.size();
}
bool empty() const {
std::shared_lock<std::shared_mutex> lock(m_mutex);
return m_container.empty();
}
// 遍历操作 - 使用共享锁
template<typename Func>
void for_each(Func&& func) const {
std::shared_lock<std::shared_mutex> lock(m_mutex);
for (const auto& item : m_container) {
func(item);
}
}
// 条件遍历 - 使用共享锁
template<typename Func>
void for_each_if(Func&& func) const {
std::shared_lock<std::shared_mutex> lock(m_mutex);
for (const auto& item : m_container) {
if (func(item)) {
break;
}
}
}
// 获取容器副本 - 使用共享锁
Container get_copy() const {
std::shared_lock<std::shared_mutex> lock(m_mutex);
return m_container;
}
// 原子操作 - 使用独占锁
template<typename Func>
void atomic_operation(Func&& func) {
std::lock_guard<std::shared_mutex> lock(m_mutex);
func(m_container);
}
// 原子查询 - 使用共享锁
template<typename Func>
auto atomic_query(Func&& func) const {
std::shared_lock<std::shared_mutex> lock(m_mutex);
return func(m_container);
}
// 对于序列容器的特殊操作
template<typename C = Container>
auto push_back(const typename C::value_type& value) ->
typename std::enable_if<std::is_same_v<C, std::vector<typename C::value_type>>, void>::type {
std::lock_guard<std::shared_mutex> lock(m_mutex);
m_container.push_back(value);
}
template<typename C = Container>
auto push_back(typename C::value_type&& value) ->
typename std::enable_if<std::is_same_v<C, std::vector<typename C::value_type>>, void>::type {
std::lock_guard<std::shared_mutex> lock(m_mutex);
m_container.push_back(std::move(value));
}
private:
Container m_container;
mutable std::shared_mutex m_mutex;
};
这是测试代码:
#include "thread_safe_container.hpp"
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <string>
#include <thread>
#include <chrono>
#include <random>
#include <future>
#include <iomanip>
// 辅助函数:打印容器内容
template<typename Container>
void print_container(const Container& container, const std::string& name) {
std::cout << "\n=== " << name << " ===" << std::endl;
for (const auto& item : container) {
if constexpr (std::is_same_v<typename Container::value_type, std::pair<const int, std::string>>) {
std::cout << "Key: " << item.first << ", Value: " << item.second << std::endl;
} else {
std::cout << item << std::endl;
}
}
}
// 测试基本操作
void test_basic_operations() {
std::cout << "\n=== Testing Basic Operations ===" << std::endl;
// 测试 map
ThreadSafeContainer<std::map<int, std::string>> safe_map;
// 插入操作
safe_map.emplace(1, "one");
safe_map.insert({2, "two"});
safe_map.try_emplace(3, "three");
// 查找操作
if (auto value = safe_map.find(1)) {
std::cout << "Found value: " << *value << std::endl;
}
// 遍历操作
safe_map.for_each([](const auto& pair) {
std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
});
// 删除操作
safe_map.erase(2);
std::cout << "Size after erase: " << safe_map.size() << std::endl;
}
// 测试并发操作
void test_concurrent_operations() {
std::cout << "\n=== Testing Concurrent Operations ===" << std::endl;
ThreadSafeContainer<std::unordered_map<int, int>> safe_map;
std::vector<std::future<void>> futures;
// 创建多个线程进行并发写入
for (int i = 0; i < 10; ++i) {
futures.push_back(std::async(std::launch::async, [&safe_map, i]() {
for (int j = 0; j < 100; ++j) {
safe_map.emplace(i * 100 + j, j);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}));
}
// 创建多个线程进行并发读取
for (int i = 0; i < 5; ++i) {
futures.push_back(std::async(std::launch::async, [&safe_map]() {
for (int j = 0; j < 1000; ++j) {
safe_map.find(j);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}));
}
// 等待所有操作完成
for (auto& f : futures) {
f.wait();
}
std::cout << "Final size: " << safe_map.size() << std::endl;
}
// 测试不同容器类型
void test_different_containers() {
std::cout << "\n=== Testing Different Container Types ===" << std::endl;
// 测试 vector
ThreadSafeContainer<std::vector<int>> safe_vec;
safe_vec.atomic_operation([](auto& vec) {
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
});
// 测试 set
ThreadSafeContainer<std::set<int>> safe_set;
safe_set.insert(1);
safe_set.insert(2);
safe_set.insert(3);
// 测试 unordered_set
ThreadSafeContainer<std::unordered_set<std::string>> safe_uset;
safe_uset.insert("hello");
safe_uset.insert("world");
// 测试 map
ThreadSafeContainer<std::map<std::string, int>> safe_map;
safe_map.emplace("one", 1);
safe_map.emplace("two", 2);
// 打印结果
safe_vec.atomic_query([](const auto& vec) {
std::cout << "Vector contents: ";
for (const auto& v : vec) std::cout << v << " ";
std::cout << std::endl;
});
safe_set.for_each([](const auto& v) {
std::cout << "Set value: " << v << std::endl;
});
safe_uset.for_each([](const auto& v) {
std::cout << "Unordered set value: " << v << std::endl;
});
safe_map.for_each([](const auto& pair) {
std::cout << "Map entry: " << pair.first << " -> " << pair.second << std::endl;
});
}
// 测试原子操作
void test_atomic_operations() {
std::cout << "\n=== Testing Atomic Operations ===" << std::endl;
ThreadSafeContainer<std::map<int, std::string>> safe_map;
// 原子写入多个值
safe_map.atomic_operation([](auto& map) {
map[1] = "one";
map[2] = "two";
map[3] = "three";
});
// 原子读取并修改
safe_map.atomic_operation([](auto& map) {
if (auto it = map.find(1); it != map.end()) {
it->second = "ONE";
}
});
// 原子查询
auto result = safe_map.atomic_query([](const auto& map) {
std::string result;
for (const auto& [key, value] : map) {
result += value + " ";
}
return result;
});
std::cout << "Atomic query result: " << result << std::endl;
}
// 测试条件遍历
void test_conditional_traversal() {
std::cout << "\n=== Testing Conditional Traversal ===" << std::endl;
ThreadSafeContainer<std::map<int, std::string>> safe_map;
// 插入一些测试数据
for (int i = 0; i < 10; ++i) {
safe_map.emplace(i, "value_" + std::to_string(i));
}
// 使用条件遍历查找特定值
bool found = false;
safe_map.for_each_if([&found](const auto& pair) {
if (pair.first == 5) {
std::cout << "Found target value: " << pair.second << std::endl;
found = true;
return true; // 停止遍历
}
return false; // 继续遍历
});
if (!found) {
std::cout << "Target value not found" << std::endl;
}
}
// 测试容器副本
void test_container_copy() {
std::cout << "\n=== Testing Container Copy ===" << std::endl;
ThreadSafeContainer<std::map<int, std::string>> safe_map;
// 添加一些数据
safe_map.emplace(1, "one");
safe_map.emplace(2, "two");
safe_map.emplace(3, "three");
// 获取容器副本
auto copy = safe_map.get_copy();
// 修改原始容器
safe_map.emplace(4, "four");
// 打印两个容器的内容
std::cout << "Original container:" << std::endl;
safe_map.for_each([](const auto& pair) {
std::cout << pair.first << " -> " << pair.second << std::endl;
});
std::cout << "\nCopied container:" << std::endl;
for (const auto& pair : copy) {
std::cout << pair.first << " -> " << pair.second << std::endl;
}
}
#include "Windows.h"
class ConsoleManager
{
public:
ConsoleManager()
{
if (m_is_console_open)
{
return;
}
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
freopen_s(&f, "CONOUT$", "w", stderr);
freopen_s(&f, "CONOUT$", "w", stdin);
m_is_console_open = true;
}
~ConsoleManager()
{
if (!m_is_console_open)
{
return;
}
FreeConsole();
m_is_console_open = false;
}
private:
bool m_is_console_open = false;
};
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd)
{
ConsoleManager t;
try {
std::cout << "Starting comprehensive tests for ThreadSafeContainer..." << std::endl;
test_basic_operations();
test_concurrent_operations();
test_different_containers();
test_atomic_operations();
test_conditional_traversal();
test_container_copy();
std::cout << "\nAll tests completed successfully!" << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Test failed with exception: " << e.what() << std::endl;
return 1;
}
return 0;
}