Mam x boostów, które działają w tym samym czasie. Jeden wątek producenta wypełnia zsynchronizowaną kolejkę z zadaniami obliczeniowymi. Nici konsumenta wyskakują z zadań i obliczają je.Naprawiono poprawnie gwinty do automatycznego wyłączania
Image Source: https://www.quantnet.com/threads/c-multithreading-in-boost.10028/
Użytkownik może zakończyć programm podczas tego procesu, więc muszę zamknięcie moje wątki prawidłowo. Moje obecne podejście wydaje się nie działać, ponieważ są zgłaszane wyjątki. Planuje się, że po zamknięciu systemu wszystkie procesy powinny zostać zabite i zatrzymać ich bieżące zadanie bez względu na to, co robią. Czy mógłbyś mi pokazać, jak zabiłbyś te wątki?
Inicjalizacja Temat:
for (int i = 0; i < numberOfThreads; i++)
{
std::thread* thread = new std::thread(&MyManager::worker, this);
mThreads.push_back(thread);
}
Zniszczenie Temat:
void MyManager::shutdown()
{
for (int i = 0; i < numberOfThreads; i++)
{
mThreads.at(i)->join();
delete mThreads.at(i);
}
mThreads.clear();
}
Pracownik:
void MyManager::worker()
{
while (true)
{
int current = waitingList.pop();
Object * p = objects.at(current);
p->calculateMesh(); //this task is internally locked by a mutex
try
{
boost::this_thread::interruption_point();
}
catch (const boost::thread_interrupted&)
{
// Thread interruption request received, break the loop
std::cout << "- Thread interrupted. Exiting thread." << std::endl;
break;
}
}
}
synchroniczne kolejki:
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
template <typename T>
class ThreadSafeQueue
{
public:
T pop()
{
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
auto item = queue_.front();
queue_.pop();
return item;
}
void push(const T& item)
{
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push(item);
mlock.unlock();
cond_.notify_one();
}
int sizeIndicator()
{
std::unique_lock<std::mutex> mlock(mutex_);
return queue_.size();
}
private:
bool isEmpty() {
std::unique_lock<std::mutex> mlock(mutex_);
return queue_.empty();
}
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
Rzucony stos wywołań błędu:
... std::_Mtx_lockX(_Mtx_internal_imp_t * * _Mtx) Line 68 C++
... std::_Mutex_base::lock() Line 42 C++
... std::unique_lock<std::mutex>::unique_lock<std::mutex>(std::mutex & _Mtx) Line 220 C++
... ThreadSafeQueue<int>::pop() Line 13 C++
... MyManager::worker() Zeile 178 C++
dwie rzeczy: isEmpty nie jest zablokowana, a wielkość() mogą mieć prostszą implementację: po mutex jest zablokowany można po prostu wrócić queue_.size() (i mlock destructor zwalnia mutex) – marom
@mamy dzięki, poprawiłem mój kod. Błąd nadal istnieje. – Anthea
Dwie rzeczy: isEmpty i size mogą nie być publiczne. Wszystkie informacje, które zgłaszają, mogą być nieważne podczas oceny przez dzwoniącego. Jeśli nie są używane prywatnie, zostaną usunięte. – stefan