2012-03-02 2 views
2

Использование async для темы в Perl сценарий мне нужно сделать некоторую параллельную функциональность, однако я должен установить лимит времени для исправления таких нитей (например, не более 5 сек). Мне нужно убить все запущенные потоки, если они работают дольше, но все равно сохранить программу в активном состоянии. Мой код:Как убить запущенные потоки и сохранить приложение perl в живых?

use threads ('yield', 
       'exit' => 'threads_only', 
       'stack_size' => 2*16384); 
use threads::shared; 
use Time::HiRes qw/sleep/; 

... 

$start = [Time::HiRes::gettimeofday()]; 
my $running :shared = 0; 
foreach ($entry) { 
    async(
    sub { 
      local $SIG{KILL} = sub { threads->exit }; 
      { lock $running; ++$running }; 

      ... 

      { lock $running; --$running }; 
     }, 
    $_)->detach; 
} 

while ($running) { 
    sleep 0.005; 
    last if (Time::HiRes::tv_interval($start) > 5); 
} 

if ($running) { 
    my @running = threads->list(threads::running); 
    foreach (@running) { 
    $_->kill('KILL')->detach; 
    } 
} 

print "I am still alive\n"; 

Есть ли лучший способ, как убить запущенные потоки и сохранить приложение в живых?

+2

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

+2

Но вы жуете хотя бы одно ядро ​​до смерти, ничего не делая, кроме проверки времени. Это дорого и тепло, и мощность. Я сделал комментарий в надежде, что кто-то, кто знает Perl лучше, чем я, заметят мой комментарий и дадут совет по замене его более эффективным кодом - что-то, что они могли пропустить, если они просто ответят на ваш вопрос напрямую. – sarnold

+0

@sarnold - я понимаю, но до сих пор кто-то еще утверждает, что ожидание не так, и никто не пришел с альтернативным решением. Что еще вы можете сделать, если вам нужно подождать? –

ответ

5

Не делайте этого. Кодируйте потоки, чтобы они выполняли только работу, которую вы хотите сделать, и завершаете себя, когда для них нет работы. Не пытайтесь войти со стороны и убить их. Это никогда не срабатывает.

+0

Что не так об убийстве тем? Когда у вас есть внутренний тайм-аут для какой-то работы, другого пути нет, просто убивайте эти медленные потоки ... –

+0

Мои темы завершают работу в 99.999% вовремя и завершают себя, но если нет, я должен их убить, поскольку мне нужны ресурсы, которые они блокируют. Понял? –

+2

@stackoverflow: Вы пишете код, в котором работают эти потоки. Кодируйте их, чтобы делать то, что вы хотите сделать, закодируйте их, чтобы они прекратились, если они больше не нужны. Тогда вам не нужно их убивать. Это не те потоки, которые медленны, это работа, которая занимает слишком много времени. Вы сосредотачиваетесь на потоках, когда проблема - это работа. –

1

async возвращает объект потока, который вы можете назвать kill on. Просто надавите на массив и убейте их потом.

http://perldoc.perl.org/threads.html

Лучше дизайн, вероятно, будет иметь нити убить себя после такого количества времени, хотя.

+2

Нитки прекращаются, как только они заканчивают работу вовремя. Преимущество проверки тайм-аута из основной программы заключается в том, что если по какой-то причине поток отключается, он все равно будет убит. В случае, если поток проверяет свой тайм-аут, я не могу быть уверен, что он всегда будет завершен. Кроме того, то, что вы видите в качестве преимущества, чтобы сохранить собственный массив потоков от async, а не использовать «threads-> list (threads :: running)» вместо этого? –

+1

@stackoverflow: использование списка запущенных потоков - это плохая модель, потому что она теряет информацию о том, что делают потоки, заставляя вас отслеживать каждую нить, создаваемую вашим кодом, и то, что она делает, в одном централизованном месте, ограбив вас гибкости при назначении работы потокам. Сосредоточение внимания на потоках - это плохое мышление, чтобы войти и привести к очень плохому коду - сосредоточьтесь на работе, которую нужно выполнить, и обрабатывать потоки как инструмент. Подумайте о таких потоках, как работники, работающие над домом - вы хотите управлять строительством дома, а не рабочими. –

+0

@David Schwartz - Я понимаю, что вы говорите, но вы не видите код потоков, поэтому вы не видите целую картину. Проблема в том, что потоки выполняют некоторые задания, которые могут в конечном итоге зависать из-за ошибок или проблем с другой стороной, с которой они общаются. И, как вы можете видеть в моем коде, я не убиваю потоки, я просто посылаю им сигнал, на основе которого они заканчиваются. Таким образом, нет реальных убийств потоков, просто форсируя для завершения (-ов). Я все еще не прав? Если да, скажите мне, что именно не так и почему именно. –