2015-03-06 3 views
2

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

Сейчас я проверяю условия в начале функции, но если условия меняются во время работы библиотечной функции, мне не нужны ее результаты и я хочу вернуться из нее.

В основном это то, что у меня есть сейчас.

def my_function(): 
    if condition_checker.condition_met(): 
     return 
    library.long_running_function() 

Есть ли способ, чтобы выполнить проверку условия каждый второй или так и возврата из my_function, когда условие выполняется?

Я думал о декораторах, сопрограммах, я использую 2.7, но если это можно сделать только в 3.x, я бы подумал о переключении, просто я не могу понять, как это сделать.

+0

Единственное, что я могу придумать, - это периодически проверять, соблюдается ли условие в долгосрочной перспективе. Если это какой-то цикл, который будет легко прорваться, но я уверен, что есть лучшее решение. – Donkyhotay

ответ

3

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

Что вы можете сделать, это вызвать библиотеку в подпроцессе, а не в потоке, поскольку процессы могут быть завершены с помощью сигналов. Модуль multiprocessing Python предоставляет API-интерфейс, напоминающий потоки, для нерестовых вилок и обработки IPC, включая синхронизацию.

Или создайте отдельный подпроцесс через subprocess.Popen, если форматирование слишком сильно зависит от ваших ресурсов (например, объем памяти при копировании родительского процесса).

К сожалению, я не могу думать о другом.

+0

Итак, в my_function я бы начал подпроцесс с библиотечной функцией, а затем дождался выполнения условия в контроле состояния (а затем остановил библиотечную функцию) или для завершения длительной функции, прежде чем я вернусь от своей функции , Я думаю, что это сработает, спасибо. – user1079328

0

Как правило, я думаю, что вы хотите запустить свой long_running_function в отдельном потоке и периодически сообщать его информацию в основной поток.

This post дает аналогичный пример в программе wxpython.

Предполагая, что вы делаете это за пределами wxpython, вы должны иметь возможность заменить wx.CallAfter и wx.Publisher на threading.Thread и PubSub.

Это будет выглядеть примерно так:

 
import threading 
import time 

def myfunction(): 
    # subscribe to the long_running_function 
    while True: 
     # subscribe to the long_running_function and get the published data 
     if condition_met: 
      # publish a stop command 
      break 
     time.sleep(1) 

def long_running_function(): 
    for loop in loops: 
     # subscribe to main thread and check for stop command, if so, break 
     # do an iteration 
     # publish some data 

threading.Thread(group=None, target=long_running_function, args=()) # launches your long_running_function but doesn't block flow 
myfunction() 

Я не использовал PubSub тонну, так что я не могу быстро взбивать код, но он должен получить вас там.

В качестве альтернативы, вы знаете критерии остановки перед запуском long_running_function? Если это так, вы можете просто передать его в качестве аргумента и проверить, выполняется ли его внутри.

+0

К сожалению, у меня нет доступа к функции long_running, но в этом случае я думаю, что могу, но мне нужно более общее решение, которое не связано с изменением библиотек. – user1079328

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