Python 开启进程和线程的两种方式
进程和线程的差别
- 开销
在发生开启进程给操作系统时,操作系统需要申请内存空间给子进程,拷贝父进程地址空间到子进程,而开启线程不需要这些步骤,因此开启进程开销远大于线程,开启速度为线程快 - 地址空间
进程之间地址空间是隔离的,开多个进程,每个进程都有不同的pid,但子进程的数据是来自于拷贝父进程的数据,进程之间存在父子进程概念。
一个进程默认分配一个线程,同一进程内开启的多个线程是共享该进程地址空间的,线程之间的关系平等,不存在什么父子关系。
启用进程
方式一: 使用面向对象
自己写一个类并且继承Process类
import time
from multiprocessing import Process
class MyProcess(Process):
def __init__(self, data, name=None):
super().__init__()
self.data = data
if name:
self.name = name
def run(self) -> None:
print(f"{self.name} 准备")
time.sleep(1)
print(f"{self.name} {self.data}")
if __name__ == '__main__':
for i in range(1, 4):
p = MyProcess("多喝热水", f"进程-{i}")
p.start()
方式二: 指定函数
将函数作为参数实例化Process类
import time
from multiprocessing import Process, current_process
def funx(data):
print(f"{current_process().name} 准备")
time.sleep(1)
print(f"{current_process().name} {data}")
if __name__ == '__main__':
for i in range(1, 4):
p = Process(target=funx, args=("在遛狗",), name=f"进程-{i}")
p.start()
启用线程
方式一: 使用面向对象
自己写一个类并且继承Thread类
import time
from threading import Thread
class MyThread(Thread):
# 继承Thread这个类
def __init__(self, data, name=None,):
super().__init__()
self.data = data
if name:
self.name = name
def run(self) -> None:
print(f"线程: {self.name} 准备")
time.sleep(1)
print(f"线程: {self.name} {self.data}")
for i in range(1, 5):
t = MyThread("在卖包子", name=f"线程-{i}")
t.start()
方式二: 指定函数
将函数作为参数实例化Thread类
import time
from threading import Thread, currentThread
def funx(data):
print(f"{currentThread().name} 准备")
time.sleep(1)
print(f"{currentThread().name} {data}")
for i in range(1, 4):
t = Thread(target=funx, args=("在遛狗",), name=f"线程-{i}")
t.start()