多进程、多线程在不同环境下的操作
多进程:Linux创建进程是操作系统把父进程的东西拷贝到子进程
Windows创建进程类似于模块导入
Linux环境下开启多进程,可以用os里的fork
1 import os 2 import time 3 pid = os.fork() 4
5 if pid == 0: # 子进程永远返回0
6 print('子进程{},父进程{}'.format(os.getpid(), os.getppid())) 7 else: # 父进程返回的是子进程的id;os.getpid()获取子进程id,os.getppid()获取父进程id
8 print('父进程开始等待子进程运行结束,子进程id:',pid) 9 time.sleep(10) 10 运行结果: 11 ssh://pyvip@127.0.0.1:1234/usr/bin/python3 -u /home/pyvip/tz_spider/os_test.py 12 父进程开始等待子进程运行结束,子进程id: 1812
13 子进程1812,父进程1811
windows环境下开启多进程,注意要写 if __name__ == '__main__': 不然会一直创建子进程
1 import multiprocessing 2 import time 3 print('mainprocess start', time.asctime(time.localtime(time.time())), multiprocessing.current_process()) 4 def func(): 5 print('subprocess start:', time.asctime(time.localtime(time.time()))) 6 time.sleep(5) 7 print('subprocess end:', time.asctime(time.localtime(time.time()))) 8 if __name__ == '__main__': 9 # is_alive 判断进程实例是否还在运行
10 # terminate 结束进程 p.terminate ; p.join()主进程会等子进程执行完再执行
11 p = multiprocessing.Process(target=func) 12 p.start() 13 time.sleep(5) 14 print('mainprocess end', time.asctime(time.localtime(time.time()))) 15 运行结果: 16 E:\python3.63\python.exe E:/tz_spider/os_test.py 17 mainprocess start Fri Mar 23 11:02:11 2018 <_MainProcess(MainProcess, started)>
18 mainprocess start Fri Mar 23 11:02:12 2018 <_MainProcess(Process-1, started)>
19 subprocess start: Fri Mar 23 11:02:12 2018
20 mainprocess end Fri Mar 23 11:02:16 2018
21 subprocess end: Fri Mar 23 11:02:17 2018
从17、18行代码可以发现 mainprocess start 打印了两次,这是因为子进程会复制该程序运行,但是 if __name__
== '__main__': 只有主进程才会执行,这是 if __name__ == '__main__': 的特性!在本文件里 __name__ == '__main__'
但是在'复制'的文件里它会变成被'复制'文件的名字。这里相当于是在其他py文件里导入模块。如果在Linux里执行,这段
代码18行将不会执行!
守护进程:
p = multiprocessing.Process(target=func)
p.deamon = True
上面的代码会让主进程直接执行,不等待子进程,主进程结束子进程也就结束了;p.join()起到一个阻塞的作用,主进
程要等子进程结束再执行!
面向对象化的多进程:
1 import multiprocessing 2 import time 3
4
5 class ClockProcess(multiprocessing.Process): 6
7 def __init__(self): 8 super().__init__() 9
10 def run(self): 11 time.sleep(3) 12 n = 5
13 while n > 0: 14 print('the time is {}'.format(time.time())) 15 n -= 1
16
17
18 if __name__ == '__main__': 19 for i in range(5): 20 p = ClockProcess() 21 p.start()
在Windows和Linux下都会下产生6个进程,一个主进程,5个子进程!注意程序里面如果有 input() ,子程序如果也要执
行这个的话就会报错 !可以导入os,sys 模块,写一行 sys.stdin = os.fdopen(0)
多线程:
线程是轻量级的进程,注意类继承时要重写 初始化 和 run 方法
1 import threading 2 import time 3 class MyThread(threading.Thread): 4 def __init__(self, name): 5 super().__init__() 6 self.name = name 7
8 def run(self): 9 print('I am is {}'.format(self.name)) 10 time.sleep(3) 11 if __name__ == '__main__': 12 start_time = time.time() 13 thread_liast = [] 14 for i in range(10): 15 t = MyThread('线程{}号'.format(i)) 16 t.start() 17 thread_liast.append(t) 18 for i in thread_liast: 19 i.join() 20 print(time.time() - start_time) 21 运行结果: 22 E:\python3.63\python.exe E:/tz_spider/test.py 23 I am is 线程0号 24 I am is 线程1号 25 I am is 线程2号 26 I am is 线程3号 27 I am is 线程4号 28 I am is 线程5号 29 I am is 线程6号 30 I am is 线程7号 31 I am is 线程8号 32 I am is 线程9号 33 3.004472494125366
守护线程:
1 import threading 2 import time 3 def func(): 4 time.sleep(6) 5 print('子线程执行结束') 6 if __name__ == '__main__': 7 t = threading.Thread(target=func) 8 # t.setDaemon(True) 执行这行代码的话,第15行将不会出现,因为主线程会一直执行不等子线程,主线程执行完,程序就执行完毕!
9 t.setName('线程1号') 10 print(t.getName(), t.name) # 返回:线程1号 线程1号
11 t.start() 12 运行结果: 13 E:\python3.63\python.exe E:/tz_spider/test.py 14 线程1号 线程1号 15 子线程执行结束