多进程-进程与线程的区别
区别:
1. 开进程的开销远大于线程
2. 同一进程内的多个线程共享该进程的地址空间
验证区别1:开进程的开销远大于线程
先来看开进程:
from multiprocessing import Process
import time
def piao(name):
print("%s piaoing" % name)
time.sleep(2)
print("%s piao end" % name)
if __name__ == '__main__':
p1 = Process(target=piao, args=("egon",))
p1.start()
print("主")
运行输出:
主 egon piaoing egon piao end
从运行结果可以看出,在p1.start()运行向操作系统发送开子进程的信号后,随即就运行了主进程的后面程序“主”,然后才执行了子进程应该运行的代码,说明开子进程是要向操作系统新申请空间的。
我们再来看看开线程:
from threading import Thread
import time
def piao(name):
print("%s piaoing" % name)
time.sleep(2)
print("%s piao end" % name)
if __name__ == '__main__':
t1 = Thread(target=piao, args=("egon",))
t1.start()
print("主")
运行结果:
egon piaoing 主 egon piao end
从结果可以看出,在t1.start()发出开线程的信号发出后,马上就执行了子线程要运行的代码,输出“egon piaoing” 然后就才输出主线程的“主”,在等待了2秒过后正常输出子线程的“egon piao end”,由此说明,开线程的效率比开进程要高很多,因为它不需要再向操作系统重新申请空间。
验证区别2:同一进程内的多个线程共享该进程的地址空间
2.1 进程是隔离的
from multiprocessing import Process
n = 100
def task():
global n
n = 0
print("n:", n)
if __name__ == '__main__':
p1 = Process(target=task, )
p1.start()
p1.join()
print("主", n)
运行输出:
n: 0 主 100
从结果可以看出:在函数外有一个n=100 ,程序开启了一个子进程,由于子进程会复制一份父进程的数据到子进程,所以子进程默认也是有n的,但是我global n ,并将n=0,实际上改的是子进程里的n,所以子进程里n最后输出为0,在主进程的n依然是100
2.2 线程是共享同一个进程的资源的
from threading import Thread
n = 100
def task():
global n
n = 0
print("n:", n)
if __name__ == '__main__':
t1 = Thread(target=task, )
t1.start()
t1.join()
print("主", n)
运行输出:
n: 0 主 0
从结果可以看出:在开启的子线程内部修改n=0,直接就将全局的都改了,所以线程资源是共享进程的资源的。
3. 来看一看pid和ppid
进程:
from multiprocessing import Process, current_process
import os
def task():
print("子进程的pid为:%s" % (current_process().pid)) # current_process()没有ppid属性
print("子进程的pid为:%s ppid为:%s" % (os.getpid(), os.getppid()))
if __name__ == '__main__':
p1 = Process(target=task, )
p1.start()
print("主进程的PID为:%s" % (current_process().pid))
运行输出:
主进程的PID为:19988 子进程的pid为:10300 子进程的pid为:10300 ppid为:19988
线程:
from threading import Thread
import os
def task():
print("子线程的pid为:%s" % (os.getpid()))
if __name__ == '__main__':
t1 = Thread(target=task, )
t1.start()
print("主线程的PID为:%s" % (os.getpid()))
运行输出:
子线程的pid为:10772 主线程的PID为:10772
从结果可以看出:因为线程里都是在同一个进程中运行的,所以都是一样的。
共有 0 条评论