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 中的线程不会给您带来太多好处),或者在另一个使用 Multiprocessing 的进程中 -

from multiprocessing import Process

def b():
    # long process

def a():
    p = Process(target=b) 
    p.start()
    ...
a()

(正如蒙库特的回答所说)。

但是 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 回答
0

由于 jsbueno 的答案不适用于所有 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()
于 2019-05-22T17:38:36.523 回答