1

我正在尝试寻找或实现一个简单的解决方案,该解决方案可以按顺序排列 Linux shell 命令,以便一次执行一个。以下是标准:

  1. 队列必须一次执行一个命令,即不能同时运行两个命令。
  2. 我没有提前的命令列表。它们将来自我的网络服务器收到的网络请求。这意味着队列可能长时间为空,并且可以同时进入 10 个请求。
  3. 我的 web 服务器只能对 shell 进行系统调用,所以这个程序/解决方案需要可以从命令行调用。
  4. 我只有一台机器,所以它不能也不需要将工作外包给多台机器。

本来我以为at命令可以做我想做的事,但唯一的问题是它没有按顺序执行命令。

我正在考虑用这些部分在 python 中实现我自己的解决方案:

  1. 有一个带有锁定文件的专用目录
  2. 排队的命令存储为单个文件,文件名包含递增的序列 ID 或时间戳或类似的东西,我将其称为“命令文件”
  3. 使用锁定文件上的模块编写 python 脚本fcntl,以确保仅运行 1 个脚本实例
  4. 该脚本将监视目录中的任何文件并按照文件名的顺序执行文件中的 shell 命令
  5. 当目录没有更多“命令文件”时,脚本将解锁锁定文件并退出
  6. 当我的网络服务器想要排队作业时,它会添加一个新的“命令文件”并调用我的 python 脚本
  7. python 脚本将检查其自身的另一个实例是否正在运行。如果是,则退出,这将让另一个实例处理新排队的“命令文件”。如果否,则锁定锁定文件并开始按顺序执行“命令文件”

这听起来会奏效吗?我不知道如何处理的唯一竞争条件是脚本的第一个实例检查目录并看到它是空的,并且在它解锁锁定文件之前,一个新命令排队并调用了脚本的新实例. 当新脚本看到文件被锁定时,它将退出。然后原始脚本将解锁文件并退出。

有没有什么东西已经这样做了,所以我不必自己实现这个?

4

2 回答 2

8

使用命名管道,又名 FIFO:

mkfifo /tmp/shellpipe

启动一个 shell 进程,其输入来自管道:

/bin/sh < /tmp/shellpipe

当 Web 服务器想要执行命令时,它会将其写入管道。

sprintf(cmdbuf, "echo '%s' > /tmp/shellpipe", command);
system(cmdbuf);
于 2012-10-22T04:28:23.007 回答
2

一个posix 消息队列似乎是为此量身定做的,而且比处理带时间戳的文件等更简单(也更快)。脚本可以在请求进入时将请求排入队列;另一个脚本将请求出列并执行它们。有一些适用于队列的大小限制,但听起来你不会接近他们。

于 2012-10-22T05:14:43.280 回答