【问题标题】:Why does Gradle task block on executing a Python script that spawns a process?为什么 Gradle 任务会阻止执行生成进程的 Python 脚本?
【发布时间】:2015-01-28 19:25:13
【问题描述】:

我在从 Gradle 任务运行 Python 脚本时遇到问题。

短版

为什么执行 Python 脚本的 Gradle 任务(Python 脚本会生成一个进程)似乎会阻塞?

加长版

背景资料

我创建了三个 Python 脚本。

  • start.py:生成两个进程,脚本退出时不会终止
  • stop.py:杀死两个产生的进程
  • test.py: 是否有print("Done")(此脚本用于调试目的。)

从我的终端/控制台本地运行所有三个 Python 脚本会执行预期的行为。

我对每个 Python 脚本都有一个 Gradle 任务,该任务调用 Python 脚本。我的 build.gradle 看起来像这样:

task start (type:Exec) {
    workingDir './mysie'
    commandLine 'python', 'start.py'
}

task stop(type:Exec) {
    workingDir './mydir'
    commandLine 'python', 'stop.py'
}

task testPython(type:Exec) {
    workingDir './mydir'
    commandLine 'python', 'test.py'
}

我要解决的问题

我正在使用 Gradle 包装器可执行文件,如果我执行 gradlew testPython,则任务运行并收到 BUILD SUCCESSFUL 消息。

$ /gradlew test
Parallel execution is an incubating feature.
:testPython
Done

BUILD SUCCESSFUL

Total time: 0.888 secs

所以这表明gradlew 可以成功执行 Python 脚本而不会阻塞。但是,当我执行gradlew start 时,会产生两个进程。重要的是不要让 Python 脚本生成两个进程,但不会终止它们。 Gradle 任务永远不会完成。它似乎被阻止了。这是我看到的输出:

$ gradlew start
Parallel execution is an incubating feature.
:start
<Insert Python "print" statement that have been flushed here>
> Building 0% > :start

我可以看到在我的主机上启动的进程。另外,在start.py 存在之前,我在控制台上显示了print("Exiting...")。所以我知道 Python 脚本执行并完成了。

在另一个终端,我执行gradle stop,成功终止进程。

这是奇怪的部分。在gradle stop命令成功完成后,之前被阻塞的gradle start突然完成。

我的问题

我需要将startstop 放在不同的任务中。所以我的问题是:

  1. 我的 build.gradle 文件中的内容看起来是否正确?
  2. 为什么 Gradle 在执行生成进程的 Python 脚本时会阻塞?
  3. 如何在 Python 脚本生成进程后“解除阻止”gradle start 任务?

【问题讨论】:

    标签: python gradle build.gradle gradlew


    【解决方案1】:
    1. build.gradle 文件的内容看起来是正确的。所有任务都已正确定义。

    2. 因为如果任务是Exec 类型,它会等到进程完成,然后任务也会完成。如果两个单独的进程是从从Exec 任务运行的 python 脚本启动的,并且它们以某种方式有界到启动它们的脚本(这是有界到 gradle 任务本身)这一切都必须完成才能让 gradle 任务也完成。以this 问题为例。

    3. 通过编写将在后台启动进程的自定义任务。请参阅上面链接的问题。

    希望这会有所帮助。如果有什么不清楚的,尽管问。

    【讨论】:

    • 感谢您的信息。链接中的信息对我有用。我只是有一个小问题。该示例似乎没有遵循 gradle DSL 语法。有没有办法让代码更像“DSL”?
    • @bkhouri,请更准确一些。你到底是什么意思?
    • 虽然代码有效,但任务中似乎有一些常规脚本。它虽然有效。此外,由于脚本在后台运行,因此 gradle 任务在脚本完成之前完成。我知道这是意料之中的,但是是否有一个 gradle 解决方案,一旦脚本存在,任务就会完成?
    • 这是一种常见的做法,这就是使用 gradle 的原因,因为它非常灵活。即使没有提供某些东西,您也可以使用 groovy 轻松实现它。你试过waitFor吗?
    猜你喜欢
    • 2014-06-25
    • 2021-02-26
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多