Я сейчас пишу многопоточный сервер C ++, используя Poco, и сейчас я нахожусь в точке, где мне нужно хранить информацию о том, какие пользователи подключены, сколько подключений у каждого из них, и, учитывая, что это прокси-сервер, где каждое из этих соединений проходит через.
Для этой цели я создал класс ServerStats, который содержит список STL объектов ServerUser. Класс ServerStats включает функции, которые могут добавлять и удалять объекты из списка, а также находить пользователя в списке и возвращать указатель на него, чтобы я мог получить доступ к функциям-членам внутри любого данного объекта ServerUser в списке.
Класс ServerUser содержит список STL объектов ServerConnection и во многом аналогичен классу ServerStats, в котором содержатся функции для добавления, удаления и поиска элементов в этом списке.
Теперь все вышеперечисленное работает, но я сейчас пытаюсь сделать его потокобезопасным.
Я определил Poco :: FastMutex в классе ServerStats и могу заблокировать / разблокировать его в соответствующих местах, чтобы контейнеры STL не изменялись одновременно с поиском, например. Однако у меня возникла проблема с настройкой взаимных исключений в классе ServerUser, и я получаю следующую ошибку компилятора:
/ корень / росо / Foundation / включить / Poco / Mutex.h:
В конструкторе копирования
âServerUser :: ServerUser (Const
ServerUser &): с
SRC / SocksServer.cpp: 185
инстанцируется из oidvoid
__gnu_cxx :: new_allocator <_Tp> :: построить (_Tp *,
const _Tp &) [with _Tp = ServerUser] â
/usr/include/c++/4.4/bits/stl_list.h:464:
созданный из
âstd :: _ List_node <_Tp> * std :: list <_Tp,
_Alloc> :: _ M_create_node (const _Tp &) [with _Tp = ServerUser, _Alloc =
станд :: Распределитель] â
/usr/include/c++/4.4/bits/stl_list.h:1407:
создается из âvoid std :: list <_Tp,
_Alloc> :: _ M_insert (std :: _ List_iterator <_Tp>, const _Tp &) [with _Tp = ServerUser,
_Alloc = std :: allocator] â /usr/include/c++/4.4/bits/stl_list.h:920:
создается из âvoid std :: list <_Tp,
_Alloc> :: push_back (const _Tp &) [с _Tp = ServerUser, _Alloc = std :: allocator] â
SRC / SocksServer.cpp: 301
созданный отсюда
/root/poco/Foundation/include/Poco/Mutex.h:164:
ошибка:
Кулако :: 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 <_Tp> :: построить (_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) â
определено, но не используется make: ***
[/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 ++ для проектов такого размера или мьютексов, так что, пожалуйста, будьте проще
Во-первых, кто-нибудь может сказать мне, почему вышеизложенное вызывает ошибку компилятора?
Во-вторых, кто-нибудь может предложить лучший способ хранения необходимой мне информации? Помните, что мне нужно обновлять эту информацию всякий раз, когда устанавливаются или исчезают соединения, и она должна быть глобальной для всего сервера.