python - 使用线程并行运行子进程

标签 python linux multithreading subprocess

我是一个Linux脚本,我希望通过子进程实现自动化。子进程的每次迭代都应该运行父目录的每个子目录中的linux脚本,并且每个子进程都应该在单独的线程中运行。

我的目录的组织方式如下:

  • /parent/p1
  • /parent/p2...等等直到
  • /parent/p[n]

我的代码的第一部分旨在跨所有子目录(p1、p2、p3...等)运行该进程。它对于快速过程来说效果很好。然而,我的许多工作需要在后台运行,为此我通常使用 nohup 并在单独的节点上手动运行它们。因此,我终端中的每个节点都将在每个目录(p1、p2、p3 等)上运行相同的作业。我的代码的后一部分(使用线程)旨在实现这一点,但最终发生的是每个节点都运行相同的进程(p1,p1,p1...等) - 基本上,当我希望它们在线程上分离时,整个“作业”函数正在通过 runSims 传递。有人知道我如何进一步迭代线程函数以在每个节点上放置不同的作业吗?

import os
import sys
import subprocess
import os.path
import threading

#takes the argument: python FOLDER_NAME #ofThreads
#Example: python /parent 8

directory = sys.argv[1] #in my case input is /parent 
threads = int(sys.argv[2]) #input is 8
category_name = directory.split('/')[-1] #splits parent as a word
folder_list = next(os.walk(directory))[1] #makes a list of subdirectories [p1,p2,p3..]

def jobs(cmd):
     for i in folder_list:
         f = open("/vol01/bin/dir/nohup.out", "w")
         cmd = subprocess.call(['nohup','python','np.py','{0}/{1}' .format(directory,i)],cwd = '/vol01/bin/dir', stdout=f)
     return cmd

def runSimThreads(numThreads):
    threads = []
    for i in range(numThreads):
         t = threading.Thread(target=jobs, args=(i,))
         threads.append(t)
         t.start()

#Wait for all threads to complete
main_thread = threading.currentThread()
for t in threads:
    if t is main_thread:
        continue
    t.join()

runSimThreads(threads)

最佳答案

那不可能是你的代码。

import os
import sys
import subprocess
import os.path
import threading

#takes the argument: python FOLDER_NAME #ofThreads
#Example: python /parent 8

threads = 8 #input is 8

...
...

for t in threads:
    print("hello")

--output:--
TypeError: 'int' object is not iterable

您在任何地方都使用相同的变量名称,这让您(或我?)感到困惑。

您还可以这样做:

def jobs(cmd):
     for i in folder_list:
         f = open("/vol01/bin/dir/nohup.out", "w")
         cmd =  "something"

您正在覆盖 cmd 参数变量,这意味着 jobs() 不应该有参数变量。

对评论1的回复:

import threading as thr
import time

def greet():
    print("hello world")

t = thr.Thread(target=greet)
t.start()
t.join()

--output:--
hello world
<小时/>
import threading as thr
import time

def greet(greeting):
    print(greeting)

t = thr.Thread(target=greet, args=("Hello, Newman.",) )
t.start()
t.join()

--output:--
Hello, Newman.

以下相当于您正在做的事情:

import threading as thr
import time

def greet(greeting):
    greeting = "Hello, Jerry."
    print(greeting)

t = thr.Thread(target=greet, args=("Hello, Newman.",) )
t.start()
t.join()

--output:--
Hello, Jerry.

任何阅读该代码的人都会问,“为什么在不使用的时候要向greet()函数传递参数?”

I'm relatively new to python

嗯,你的代码是这样做的:

threads = 8 

#Other irrelevant stuff here

for t in threads:
    print("hello")

这会产生错误:

TypeError: 'int' object is not iterable

你知道为什么吗?

关于python - 使用线程并行运行子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41687753/

相关文章:

linux - 在 Fedora 17 上安装 Boost.Log

java - ScheduledExecutorService 如何处理终止的线程?

python - 我应该如何提取 % 分隔标签

python - 如何只向用户询问一次符号值而不是在每次迭代中?

python - Python 的 Twisted 中 LoopingCall 和 callInThread 的区别

linux - 将脚本通过管道传输到 ssh,无法设置变量

linux - 有什么有效的方法可以轻松获取Unix下Go程序的panic log吗?

Java - 多队列生产者消费者

java - 从线程中的 Java TCP 套接字读取

python - 在 Python 中削减列表字典