Здравствуйте, Selavi, Вы писали:
EP>>А до этого что, плохие были?
S>Да, были плохие. В основном они касались оформления кода и внимательности при чтении задания. Проблем реализации многопоточного пула коснулись только Вы.
Проблемы это же не только явные баги, но и неудачные технические решения. Например выше говорили про лишний поток, или проблемы с жизненным циклом объектов — это вполне объективные недостатки, а не "просто оформление". А не следование API заданному в ТЗ — вообще выглядит как намеренная диверсия.
S>>>А не могли бы подробней про 2 и 3?
EP>>2. Рассмотри ситуацию когда рабочий поток создался, не получил ни одного задания, а потом разрушился. В этом случае поток проснётся и попробует выполнять this->task, который указывает в никуда.
S>Да, но это дело обернуто в try..catch и ничего плохого не случится. Ошибка залогируется и едем дальше.
Это Undefined Behaviour — в лучшем случае получишь segmentation fault, в худшем — выполнение произвольного кода с последующим penetration.
S>Хотя, конечно, надо добавить проверку на nullptr
Это не поможет, там остаётся возможность выполнения последнего задания дважды (даже не считая spurious wakeup).
EP>>3. Управляющий поток CThreadPoolX создаётся, но нигде ни join'ится, ни detach'ится. В таком случае деструктор std::thread сделает std::terminate.
S>Как так? В деструкторе же join-ится
S>S>CThreadPoolX::~CThreadPoolX()
S>{
S> terminated = true;
S> jobCV.notify_one();
S> thread.join();
S>}
S>
Только что скачал этот файл заново:
CThreadPoolX::~CThreadPoolX()
{
}