Я пытаюсь реализовать многопоточный фреймворк, в котором выходные объекты создаются в конце каждого фрейма, который запускает мой сетевой поток, чтобы другой поток мог в начале своего фрейма получить самый последний завершенный выходной "указатель и знайте, что он имеет безопасный и полный доступ только для чтения к любым данным, хранящимся в выходном объекте.
Мой (очень ранний) подход к этому прежде всего включает следующие блоки кода:
NetworkHandler -
void NetworkHandler::Tick()
{
// Tick on our io_service
m_ios.poll();
// Assemble new output data
this->AssembleOutput();
}
ClientNetworkHandler -
void ClientNetworkHandler::AssembleOutput()
{
std::tr1::shared_ptr<crusade::task::TaskOutput> newOutput(new crusade::task::TaskOutput());
newOutput->m_outputElements["connected"] = std::tr1::shared_ptr<crusade::task::TaskOutputElement>(new NetworkConnectedTaskOutputElement(this->m_isConnected));
this->m_latestOutput.swap(newOutput);
}
PyCruHandler -
void PyCruHandler::Tick()
{
printf("PyCruHandler\n");
// Get any necessary inputs from other threads
m_latestNetworkOutput.swap(crusade::task::THManager::GetInstance()->GetTaskHandler(crusade::task::THManager::TH_NETWORK)->GetLatestOutput());
// Other unrelated processing to go here
}
Обычно ClientNetworkHandler и PyCruHandler работают независимо в отдельных потоках. PyCruHandler фактически никогда ничего не делает со своей копией m_latestNetworkOutput; Я прокомментировал все остальные экземпляры, где к нему обращались каким-либо образом, и у меня все еще есть следующая проблема:
Если я позволю обоим потокам вызывать swap (или оператор = эквивалент), то в конечном итоге (обычно в течение 2 секунд после запуска, но иногда это занимает несколько минут) я получу следующую ошибку либо для оператора new, либо для allocator удаление какого-либо вида:
"HEAP: блок свободной кучи 2bab3b0, измененный на 2bab3dc после освобождения
Windows сработала точка останова.
Это может быть связано с повреждением кучи, что указывает на ошибку ... и т. Д. "
Я только новичок, но мне кажется, что это указывает на некоторую проблему с проблемами безопасности потоков и доступа к времени между объектами shared_ptr. Тем не менее, я был смущен путаницей объяснений (как здесь, так и в других местах) нюансов потоковой безопасности shared_ptr - одна часть чтения указывает, что счетчик ссылок является поточно-ориентированным, поэтому безопасно копировать shared_ptrs вокруг (но их внутренние объекты) не будет потокобезопасным), другие части чтения указывают на то, что в shared_ptr нет никакой безопасности потоков, какой-либо полезности. Я прочитал дополнительную документацию по безопасности потоков в shared_ptrs, но это все еще не прояснило, должно ли это быть проблемой в моем коде.
Мой вопрос: может ли кто-нибудь здесь обнаружить какой-либо очевидный недостаток в том, что я делаю? Моя цель состоит в том, чтобы я мог получить доступ к последнему объекту вывода, все еще сохраненному потоком-владельцем, и тогда этот объект не будет удален (даже после того, как поток-владелец перейдет к более поздним выводам), пока каждый пользователь вывода не завершит его. также. Мне показалось, что общий указатель идеально подходит для этого ... но после 3 часов удара головой я начинаю удивляться ...
Заранее большое спасибо, и я прошу прощения, если я как-то написал это неправильно; Я впервые здесь, и часто задаваемые вопросы кажутся довольно непринужденными в том, что касается протокола!