14

こんにちは、関数/メソッド (できれば Python または Java) を呼び出して、それを待たずに実行を続ける方法があるかどうか疑問に思っていました。

例:

def a():
    b()  #call a function, b()
    return "something"

def b():
    #something that takes a really long time
4

6 に答える 6

26

新しいスレッドで実行します。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
于 2012-07-13T02:46:22.897 に答える
6

他の回答で述べたように、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]$ 
于 2012-07-13T03:26:07.447 に答える
4

Python でマルチプロセッシングを使用する:

from multiprocessing import Process

def b():
    # long process

p = Process(target=b) 
p.start()
于 2012-07-13T02:55:19.043 に答える
3

Java には、スレッドを作成して実行するという標準的なイディオムがあります。

new Thread() {
    @Override
    public void run() {
        callMyFunction();
    }
}.start();

または、Runnable を作成してスレッドに渡すこともできます。

Runnable caller = new Runnable() {
    @Override
    public void run() {
        callMyFunction();
    }
}

new Thread(caller).start();
于 2012-07-13T02:47:16.890 に答える
1

生のスレッドを直接使用するのではなく、 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 に送信できます。それらは、選択した実装、バッキング スレッド プール内のスレッドの数などに応じて、並列または順次に実行されます。

于 2012-07-13T07:31:38.643 に答える