こんにちは、関数/メソッド (できれば Python または Java) を呼び出して、それを待たずに実行を続ける方法があるかどうか疑問に思っていました。
例:
def a():
b() #call a function, b()
return "something"
def b():
#something that takes a really long time
新しいスレッドで実行します。Java のマルチスレッドについてはこちら、Python のマルチスレッドについてはこちらをご覧ください。
Java の例:
new Thread() {
public void run() {
YourFunction();//Call your function
}
}.start();
Runnable myrunnable = new Runnable() {
public void run() {
YourFunction();//Call your function
}
}
new Thread(myrunnable).start();//Call it when you need to run the function
他の回答で述べたように、Pythonからは、関数を新しいスレッドに入れるか(CPythonのスレッドはあまり得られないため、あまり良くありません)、マルチプロセッシングを使用して別のプロセスに入れることができます-
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()
このスニペットを実行すると、次のようになります。
[gwidion@caylus 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
[gwidion@caylus Documents]$
Python でマルチプロセッシングを使用する:
from multiprocessing import Process
def b():
# long process
p = Process(target=b)
p.start()
Java には、スレッドを作成して実行するという標準的なイディオムがあります。
new Thread() {
@Override
public void run() {
callMyFunction();
}
}.start();
または、Runnable を作成してスレッドに渡すこともできます。
Runnable caller = new Runnable() {
@Override
public void run() {
callMyFunction();
}
}
new Thread(caller).start();
生のスレッドを直接使用するのではなく、 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 に送信できます。それらは、選択した実装、バッキング スレッド プール内のスレッドの数などに応じて、並列または順次に実行されます。