Множество разделенных бустом тем Segfault

Я создаю потоки повышения внутри функции с

while(trueNonceQueue.empty() && block.nNonce < std::numeric_limits<uint64_t>::max()){
if ( block.nNonce % 100000 == 0 )
{
cout << block.nNonce << endl;
}
boost::thread t(CheckNonce, block);
t.detach();
block.nNonce++;
}
uint64 trueNonce;
while (trueNonceQueue.pop(trueNonce))
block.nNonce = trueNonce;

trueNonceQueue был создан с boost::lockfree::queue<uint64> trueNonceQueue(128); в глобальном масштабе.

Это функция с резьбой

void CheckNonce(CBlock block){
if(block.CheckBlockSilently()){
while (!trueNonceQueue.push(block.nNonce))
;
}
}

Я заметил, что после того, как он потерпел крах, мой обмен незначительно вырос, что никогда не произойдет, если только я не использую плохую технику, как это после утечки памяти; в противном случае, мое использование памяти часто остается ниже 2 гигов. Я запускаю cinnamon на рабочем столе Ubuntu с Chrome и несколькими другими небольшими открытыми программами. Я не использовал компьютер в то время, когда он работал.

Сегфоут произошел после 949900000итерация Как это можно исправить?


CheckNonce время исполнения

Я добавил тот же модуль для CheckNonce чтобы увидеть, было ли какое-либо отставание. Пока нет ни одного.

Я буду обновлять, если отдельные потоки начнут отставать от нереста while,

0

Решение

Вместо этого вы должны использовать пул потоков. Это означает, что порождается достаточно потоков, чтобы выполнить работу без чрезмерной конкуренции (например, вы можете порождать что-то вроде потоков N-2 на машине с N-ядром, но, возможно, больше, если какая-то работа может заблокировать ввод-вывод).

В Boost нет точно пула потоков, но есть части, которые вам нужны для его создания. Смотрите здесь для некоторых идей: boost :: threadpool :: pool vs.boost :: thread_group

Или вы можете использовать более готовое решение, подобное этому (хотя оно немного устарело и, возможно, не поддерживается, не уверен): http://threadpool.sourceforge.net/

Тогда идея состоит в том, чтобы порождать N потоков, а затем в вашем цикле для каждой задачи, просто «опубликовать» задачу в пуле потоков, где следующий доступный рабочий поток ее заберет.

Сделав это, вы избежите многих проблем, таких как нехватка места в стеке потоков, избежание неэффективной конкуренции за ресурсы (посмотрите «проблема громового стада»), и вы сможете легко настроить агрессивность, с которой вы используете несколько ядер. в любой системе.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]