0

Heads up: Я не очень хорошо знаком с работой с threadpool, что может быть очевидно из следующего кода. У меня создается впечатление, что я мог бы вставить много значений в эту очередь, а затем он будет ждать завершения одного потока, а затем перейти к следующему, и система будет обрабатывать синхронизацию количества потоков, которые будут запущены.Threadpool queueuserworkitem со многими потоками

Я пытаюсь использовать ThreadPool :: QueueUserWorkItem (waitcallback, num), где значение num повторяется до динамического значения в зависимости от некоторого предшествующего алгоритма. Проблема, с которой я сталкиваюсь, - это сбой программы, когда она становится слишком высокой.

WaitCallback^ wcb = gcnew WaitCallBack(this, &createImage); 
for(int i = 0; i < numBlocks; i++) 
{ 
    ThreadPool::QueueUserWorkItem(wcb, i); 
} 

Я получаю сообщение «Ошибка выполнения Это приложение просил Runtime прекратить его необычным способом. Пожалуйста, свяжитесь со службой поддержки приложения для получения дополнительной информации.»

Мой самый негодуют пробежать имел numBlocks = 644.

+1

Ваш код называется terminate(). Это обычно потому, что неуправляемый код бросил исключение C++, и он не был пойман. Ничего общего с опубликованным фрагментом. Обязательно отлаживайте код с отладчиком, работающим в смешанном режиме. –

+0

Если это так, возможно, это связано с тем, что я делаю преобразование изображения, прежде чем я запускал задачу линейным способом, и я всегда мог предположить, что файл был закрыт, из которого я читаю. Теперь, я спрашиваю, возможно ли, что этот тип исключения может быть из нескольких потоков, пытаясь открыть один и тот же файл? –

+0

Несомненно, это не сработает. Он также не требует нескольких потоков, вам определенно необходимо улучшить обработку ошибок. –

ответ

1

Трудно сказать, что послужило причиной к аварийному завершению программы. Скорее всего, исключение было выбрано в одном из потоков, и это привело к снижению программы. Вы должны определить, где в вашем коде было исключено исключение.

Как известно, ThreadPool::QueueUserWorkItem ставит в очередь объект для обработки threadpool. Но в этой очереди может быть несколько потоков, обрабатывающих элементы. Например, у вас может быть 20 потоков пулов, причем 15 из них обрабатывают рабочие элементы, которые вы поставили в очередь.

Если у вас действительно есть много элементов для обработки, и вы хотите, чтобы они выполнялись по одному, почему бы просто не поставить очередь одного потока, чтобы делать их по одному. Я никогда не управлял C++, поэтому я не буду пытаться написать пример с ним. Но, возможно, вы можете перевести этот код C#:

void ProcessInBackground(object state) 
{ 
    int numBlocks = (int)state; 
    for (int i = 0; i < numBlocks; ++i) 
    { 
     createImage(i); 
    } 
} 

И тогда вы можете назвать его:

ThreadPool::QueueUserWorkItem(ProcessInBackground, numBlocks); 

Это создает единый поток, который будет обрабатывать детали в порядке.

Я подозреваю, что вы можете легко преобразовать это в управляемый C++.

+0

Я поставил их в очередь, чтобы запускать 1 за раз, но затем программа заняла 4 дня. Мне нужно разделить процесс так, чтобы он был не таким линейным, но вместо этого выполнял сразу несколько преобразований (createImage (int)). Я пытаюсь создать и управлять несколькими потоками функции createImage. Я мог бы сделать это вручную, но я подумал, что QueueUserWorkItem, оптимизировал программу на основе моей машины. –

+1

@GeneParmesan: вы должны изучить Parallel.ForEach и параллельную библиотеку задач. Они будут лучше выполнять выделение потоков, чем вы можете легко сделать с помощью API-интерфейса ThreadPool. –

Смежные вопросы