多进程_subprocess
一、说明
subprocess为新启动的子进程,不是主进程
cmd的命令的返回结果,会存进pip所在的缓存区域里
统计文件有多少行 wc -l a.txt
ls -al|wc -l#ls的命令执行的结果通过管道流给了wc命令去使用
#ls的结果存在了缓存区域,后面的命令可以直接在缓存里取到
>>> import subprocess>>> a = subprocess.Popen('mkdir subprocesstest',shell=True,cwd='e:\\test')#Popen,cwd是当前路径下 #参数说明:shell命令;是否用shell命令执行;路径
二、实例:列出文件目录的内容
1、Windows下执行:
subprocess.run(args=['dir','test'],shell=True,cwd="e:\\")#dir是命令,后面的test是参数
运行结果:
2、linux下执行
subprocess.call("ls -l",shell=True,cwd="/home")
三、Subprocess 模块的基本使用方法(通过管道执行python命令)
import subprocessobj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)obj.stdin.write(b"print(1);")#无;会有报错obj.stdin.write(b"print(2);")#无;obj.stdin.write(b"print(3);")#无;obj.stdin.write(b"print(4);")#无;obj.stdin.close()cmd_out = obj.stdout.read()obj.stdout.close()cmd_error = obj.stderr.read()obj.stderr.close()print(cmd_out)print(cmd_error)
运行结果:(print代码行有误时:无;)
运行结果:(print代码行正确时:有;)
import subprocessobj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)obj.stdin.write(b"print(1)\n")obj.stdin.write(b"print(2)\n")obj.stdin.write(b"print(3)\n")obj.stdin.write(b"print(4)\n")obj.stdin.close()cmd_out = obj.stdout.read()obj.stdout.close()cmd_error = obj.stderr.read()obj.stderr.close()print(cmd_out)print(cmd_error)
运行结果:
另一种写法
import subprocessobj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)obj.stdin.write(b"print(1)\n")obj.stdin.write(b"print(2)\n")obj.stdin.write(b"print(3)\n")obj.stdin.write(b"print(4)\n")out_info,out_error = obj.communicate()#简单写法,out_info:标准输出print(out_info,out_error)
运行结果:
四、 linux下执行两个命令:
import subprocesschild1 = subprocess.Popen(["cat","/home/wxh/a.py"], stdout=subprocess.PIPE)child2 = subprocess.Popen(["wc","-l"],stdin=child1.stdout, stdout=subprocess.PIPE)#输入内容是子进程1的输出内容
out = child2.communicate()print(out)
运行结果:
五、Subprocess进程通信实例
import subprocessimport osclass Shell(object) : def runCmd(self, cmd) : res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # 获取子进程的标准输出,标准错误信息 sout, serr = res.communicate() #sout:执行命令后的输出内容,serr出错内容,res.pid为进程编号 return res.returncode, sout, serr, res.pid shell = Shell()fp = open('e:\\ip.txt', 'r',encoding="utf-8")ipList = fp.readlines()fp.close()fp = open('e:\\ping.txt', 'a',encoding="utf-8")print(ipList)for i in ipList : i = i.strip() result = shell.runCmd('ping ' + i) if result[0] == 0 : w = i + ' : 0' fp.write(w + '\n') else : w = i + ' : 1' fp.write(w + '\n') #print( result[1].decode("gbk"))fp.close()
数据文件内容:
Ip.txt
www.baidu.comwww.taobao.com123.45.5.34127.0.0.1
六、设置日志输出到控制台
#encoding=utf-8import multiprocessingimport loggingimport sysdef worker(): print('I am working....') sys.stdout.flush()#让日志信息立即输出,一般是累积到一定程度之后才输出
if __name__ == '__main__': # 设置日志输出到控制台 multiprocessing.log_to_stderr() logger = multiprocessing.get_logger() # 设置输出日志的级别(info/error) logger.setLevel(logging.INFO) p = multiprocessing.Process(target = worker) p.start() p.join()
运行结果参照:
七、守护进程(子进程、主进程共同进退)
#encoding=utf-8import multiprocessingimport time, loggingimport sys #守护进程的方法def daemon(): p = multiprocessing.current_process() print('Starting:', p.name, p.pid) sys.stdout.flush() # 将缓冲区数据写入终端 # time.sleep(2) print('Exiting :', p.name, p.pid) sys.stdout.flush() #非守护进程的方法def non_daemon(): p = multiprocessing.current_process() print('Starting:', p.name, p.pid) sys.stdout.flush() print('Exiting :', p.name, p.pid) sys.stdout.flush()if __name__ == '__main__': # 设置日志输出到控制台 multiprocessing.log_to_stderr() logger = multiprocessing.get_logger() # 设置输出日志的级别 logger.setLevel(logging.DEBUG) d = multiprocessing.Process(name='daemon', target=daemon) d.daemon = True#是守护进程 n = multiprocessing.Process(name='non-daemon', target=non_daemon) n.daemon = False#非守护进程 d.start() time.sleep(1) n.start() # d.join(1) # n.join() print('d.is_alive()', d.is_alive()) print("n.is_alive()", n.is_alive()) print("main Process end!")
运行结果: