Вызовите функцию, не дожидаясь ее
Привет, мне было интересно, есть ли способ вызвать функцию/метод (желательно на Python или Java) и продолжить выполнение, не дожидаясь его.
Пример:
def a():
b() #call a function, b()
return "something"
def b():
#something that takes a really long time
Ответы
Ответ 1
Запустите его в новой теме. Узнайте о многопоточности в Java здесь и многопоточности Python здесь
Пример Java:
НЕПРАВИЛЬНЫЙ способ... путем подкласса Thread
new Thread() {
public void run() {
YourFunction();//Call your function
}
}.start();
ПРАВИЛЬНЫЙ способ... путем предоставления Runnable экземпляра
Runnable myrunnable = new Runnable() {
public void run() {
YourFunction();//Call your function
}
}
new Thread(myrunnable).start();//Call it when you need to run the function
Ответ 2
Используя multiprocessing в python:
from multiprocessing import Process
def b():
# long process
p = Process(target=b)
p.start()
Ответ 3
Как отмечалось в других ответах, из Python вы можете либо поместить функцию в новый поток (не так уж хорошо, поскольку потоки в CPython вас не очень много) или в другом процессе с использованием Multiprocessing -
from multiprocessing import Process
def b():
# long process
def a():
p = Process(target=b)
p.start()
...
a()
(Как указано в ответе monkut).
Но декоратор Python позволяет скрывать шаблон под ковром, таким образом, что во время вызова вы "видите" только обычный вызов функции. В приведенном ниже примере,
Я создаю "параллельный" декоратор - просто поместите его перед любой функцией, и он будет автоматически запускаться в отдельном процессе при вызове:
from multiprocessing import Process
from functools import partial
from time import sleep
def parallel(func):
def parallel_func(*args, **kw):
p = Process(target=func, args=args, kwargs=kw)
p.start()
return parallel_func
@parallel
def timed_print(x=0):
for y in range(x, x + 10):
print y
sleep(0.2)
def example():
timed_print(100)
sleep(0.1)
timed_print(200)
for z in range(10):
print z
sleep(0.2)
if __name__ == "__main__":
example()
При запуске этого фрагмента вы получаете:
[[email protected] Documents]$ python parallel.py
100
0
200
101
1
201
102
2
202
103
3
203
104
4
204
105
5
205
106
6
206
107
7
207
108
8
208
109
9
209
[[email protected] Documents]$
Ответ 4
В Java есть стандартная идиома: создайте поток и запустите его:
new Thread() {
@Override
public void run() {
callMyFunction();
}
}.start();
Или вы можете создать Runnable и передать его в поток:
Runnable caller = new Runnable() {
@Override
public void run() {
callMyFunction();
}
}
new Thread(caller).start();
Ответ 5
Лучше начинать с ExecutorService вместо того, чтобы идти напрямую с необработанными потоками.
Он обеспечивает объединение, завершение обнаружения, и есть подклассы, которые также имеют некоторое планирование. Например:
...
// Create a simple instance with a single thread in the pool
ExecutorService executor = Executors.newFixedThreadPool(1);
...
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() {
return YourFunction();
}
});
...
// To wait for YourFunction() to finish, and get the result:
Integer result = future.get();
Вы можете отправить столько асинхронных задач в ExecutorService, сколько захотите; они будут выполняться параллельно или последовательно, в зависимости от выбранной вами реализации, от количества потоков в пуле поддерживающих потоков и т.д.
Ответ 6
просто вызовите эту функцию в новом потоке...
Ответ 7
Поскольку jsbueno answer не будет работать во всех системах Windows, так как os.fork не будет работать там эффективно из-за ограничений в ОС, вам придется использовать многопоточность там для достижения того же эффекта.
Пожалуйста, найдите тот же код из ответа jsbueno с многопоточностью вместо многопроцессорности (версия Python 3)
from threading import Thread
from time import sleep
def thread_parallel(func):
def parallel_func(*args, **kw):
p = Thread(target=func, args=args, kwargs=kw)
p.daemon = True
p.start()
return parallel_func
@thread_parallel
def timed_print(x=0):
for y in range(x, x + 10):
print(y)
sleep(0.2)
def example():
timed_print(100)
sleep(0.1)
timed_print(200)
for z in range(10):
print(z)
sleep(0.2)
if __name__ == "__main__":
example()