多进程、多线程在不同环境下的操作
多进程: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 子线程执行结束