首页 » 编程 » Python » Python学习 » 网络编程进阶 » 正文

进程与线程的区别

区别:

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

从结果可以看出:因为线程里都是在同一个进程中运行的,所以都是一样的。

发表评论

*