在 Rails 应用程序(或 sinatra)中,如果我调用 shell 命令,该命令在什么上下文中运行?
我不确定我的问题是否正确,但它是否与 rails 进程在同一个线程中运行?
当您掏出钱时,是否可以进行异步调用?如果是,这是否意味着在操作系统级别它将启动一个新线程?它可以从线程池而不是新线程开始吗?
在 Rails 应用程序(或 sinatra)中,如果我调用 shell 命令,该命令在什么上下文中运行?
我不确定我的问题是否正确,但它是否与 rails 进程在同一个线程中运行?
当您掏出钱时,是否可以进行异步调用?如果是,这是否意味着在操作系统级别它将启动一个新线程?它可以从线程池而不是新线程开始吗?
如果您使用system('cmd')
或只是反引号:
`cmd`
然后该命令将在子shell 的上下文中执行。如果你希望一次运行多个,你可以使用 Rubys fork 功能:
fork { system('cmd') }
fork { system('cmd') }
这将创建多个子进程,它们在各自的子外壳中运行各个命令。
在此处阅读分叉:http ://www.ruby-doc.org/core-2.0/Process.html#method-c-fork
它不仅仅是一个新线程,它是一个完全独立的过程。它将是同步的,并且在命令完成之前控制不会返回给 Ruby。如果您想要一个即发即弃的解决方案,您可以简单地将任务置于后台:
$ irb
irb(main):001:0> system("sleep 30 &")
=> true
irb(main):002:0>
$ ps ax | grep sleep
3409 pts/4 S 0:00 sleep 30
您可以通过system("foo &")
或启动任意数量的进程`foo &`
。
如果您想更好地控制从 Ruby 启动后台进程,包括正确分离 tty 和许多其他东西,请查看daemons gem。这更适合您想要管理的长时间运行的进程,使用 PID 文件等,但也可以使用它来启动任务。
根据您的需要,有用于管理后台进程的替代解决方案。resque gem在排队和管理后台作业方面很受欢迎。它需要 Redis 和一些设置,但如果您需要那种级别的控制,那就太好了。