我目前正在使用Poco编写多线程C ++服务器,现在我需要保存有关连接哪些用户,每个用户有多少连接以及给定它是代理服务器的信息,这些连接代理到。
为此,我创建了一个ServerStats类,其中包含ServerUser对象的STL列表。 ServerStats类包括一些函数,这些函数可以在列表中添加和删除对象,以及在列表中找到用户并返回指向它们的指针,因此我可以访问列表中任何给定ServerUser对象中的成员函数。
ServerUser类包含ServerConnection对象的STL列表,与ServerStats类非常相似,它包含在此列表中添加,删除和查找元素的功能。
现在以上所有方法都可以正常工作,但是我现在正在尝试使其成为线程安全的。
我已经在ServerStats类中定义了Poco :: FastMutex,并且可以在适当的位置锁定/解锁它,以便例如在搜索时不会同时修改STL容器。但是,在ServerUser类中设置互斥锁时遇到了问题,并且遇到以下编译器错误:
/root/poco/Foundation/include/Poco/Mutex.h:
在复制构造函数中
âServerUser:: ServerUser(const
ServerUser&)â:
src / SocksServer.cpp:185:
从void实例化
__gnu_cxx :: new_allocator :: construct(_Tp *,
const _Tp&)[with _Tp = ServerUser]â
/usr/include/c++/4.4/bits/stl_list.h:464:
从实例化
std :: _ List_node * std :: list _Alloc> :: _ M_create_node(const _Tp&)[其中_Tp = ServerUser,_Alloc =
std :: allocator]â
/usr/include/c++/4.4/bits/stl_list.h:1407:
从void std :: list _Alloc> :: _ M_insert(std :: _ List_iterator ,const _Tp&)[with _Tp = ServerUser,
_Alloc = std :: allocator]â/usr/include/c++/4.4/bits/stl_list.h:920:
从void std :: list _Alloc> :: push_back(const _Tp&)[with _Tp = ServerUser,_Alloc = std :: allocator]â
src / SocksServer.cpp:301:
从这里实例化
/root/poco/Foundation/include/Poco/Mutex.h:164:
错误:
âPoco:: FastMutex :: FastMutex(const
Poco :: FastMutex&)â是私有的
src / SocksServer.cpp:185:错误:在
此上下文包含在文件中
/usr/include/c++/4.4/x86_64-linux-gnu/bits/c++allocator.h:34,
来自/usr/include/c++/4.4/bits/allocator.h:48,
从/usr/include/c++/4.4/string:43,
来自/root/poco/Foundation/include/Poco/Bugcheck.h:44,
来自/root/poco/Foundation/include/Poco/Foundation.h:147,
从/root/poco/Net/include/Poco/Net/Net.h:45,
来自/root/poco/Net/include/Poco/Net/TCPServerParams.h:43,
来自src / SocksServer.cpp:1:
/usr/include/c++/4.4/ext/new_allocator.h:
在成员函数中避免
__gnu_cxx :: new_allocator :: construct(_Tp *,
const _Tp&)[with _Tp = ServerUser]â:
/usr/include/c++/4.4/ext/new_allocator.h:105:
注:合成方法
âServerUser:: ServerUser(const
ServerUser&)–首先需要在这里
src / SocksServer.cpp:在全局范围内:
src / SocksServer.cpp:118:警告:
âstd:: string getWord(std :: string)â
定义但未使用的品牌:***
[/root/poco/SocksServer/obj/Linux/x86_64/debug_shared/SocksServer.o]
错误1
ServerStats,ServerUser和ServerConnection类的代码如下:
class ServerConnection
{
public:
bool continue_connection;
int bytes_in;
int bytes_out;
string source_address;
string destination_address;
ServerConnection()
{
continue_connection = true;
}
~ServerConnection()
{
}
};
class ServerUser
{
public:
string username;
int connection_count;
string client_ip;
ServerUser()
{
}
~ServerUser()
{
}
ServerConnection* addConnection(string source_address, string destination_address)
{
//FastMutex::ScopedLock lock(_connection_mutex);
ServerConnection connection;
connection.source_address = source_address;
connection.destination_address = destination_address;
client_ip = getWord(source_address, ":");
_connections.push_back(connection);
connection_count++;
return &_connections.back();
}
void removeConnection(string source_address)
{
//FastMutex::ScopedLock lock(_connection_mutex);
for(list<ServerConnection>::iterator it = _connections.begin(); it != _connections.end(); it++)
{
if(it->source_address == source_address)
{
it = _connections.erase(it);
connection_count--;
}
}
}
void disconnect()
{
//FastMutex::ScopedLock lock(_connection_mutex);
for(list<ServerConnection>::iterator it = _connections.begin(); it != _connections.end(); it++)
{
it->continue_connection = false;
}
}
list<ServerConnection>* getConnections()
{
return &_connections;
}
private:
list<ServerConnection> _connections;
//UNCOMMENTING THIS LINE BREAKS IT:
//mutable FastMutex _connection_mutex;
};
class ServerStats
{
public:
int current_users;
ServerStats()
{
current_users = 0;
}
~ServerStats()
{
}
ServerUser* addUser(string username)
{
FastMutex::ScopedLock lock(_user_mutex);
for(list<ServerUser>::iterator it = _users.begin(); it != _users.end(); it++)
{
if(it->username == username)
{
return &(*it);
}
}
ServerUser newUser;
newUser.username = username;
_users.push_back(newUser);
current_users++;
return &_users.back();
}
void removeUser(string username)
{
FastMutex::ScopedLock lock(_user_mutex);
for(list<ServerUser>::iterator it = _users.begin(); it != _users.end(); it++)
{
if(it->username == username)
{
_users.erase(it);
current_users--;
break;
}
}
}
ServerUser* getUser(string username)
{
FastMutex::ScopedLock lock(_user_mutex);
for(list<ServerUser>::iterator it = _users.begin(); it != _users.end(); it++)
{
if(it->username == username)
{
return &(*it);
}
}
return NULL;
}
private:
list<ServerUser> _users;
mutable FastMutex _user_mutex;
};
现在,我从未将C ++用于这种规模的项目或互斥量,所以请轻松一点:)
首先,谁能告诉我为什么以上原因导致编译器错误?
其次,有人可以建议一种更好的方式来存储我需要的信息吗?请记住,无论何时出现连接,我都需要更新此信息,并且它对于整个服务器都是全局的。
最佳答案
问题在于FastMutex不可复制,因此ServerUser不可复制。将对象插入STL容器时,必须将其复制。我认为您将不得不更改类的设计。
另外,您必须非常小心地返回指向存储在STL容器中的对象的指针,因为由于在您插入和删除容器中的对象时对象被重新排序,它们可能变得无效。
关于c++ - 跨子类的C++互斥体和STL列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2817096/