python中多进程与多线程的详细区别
不同点
眼见的不同点
1:使用的模块不一样
Python支持multi-process以创建多进程。 Python支持thread以threading的方式创建多线程。
2:创建方式:
多线程的创建
方式1:创建threading.Thread对象
import threading
def tstart(arg):
print(f"{arg}running" )
if __name__ == '__main__':
t1 = threading.Thread(target=tstart, args=('This is thread 1',))
t2 = threading.Thread(target=tstart, args=('This is thread 2',))
t1.start()
t2.start()
print("This is main function")
方式2:继承threading.Thread,并重写run
import threading
import time
class CustomThread(threading.Thread):
def __init__(self, thread_name):
super(CustomThread, self).__init__(name=thread_name)
self._tname = thread_name
def run(self):
time.sleep(0.5)
print("This is %s running...." % self._tname)
if __name__ == "__main__":
t1 = CustomThread("thread 1")
t2 = CustomThread("thread 2")
t1.start()
t2.start()
print("This is main function")
创建进程
方式一:
import multiprocessing
import time
def down():
for i in range(101):
print(f"已下载{i}%")
time.sleep(1)
if i >= 100:
return f"已下载{i}%"
def upload():
for i in range(101):
print(f"已上传{i}%")
time.sleep(1)
if i >= 100:
return f"已上传{i}%"
if __name__ == "__main__":
ser1 = multiprocessing.Process(target=down)
ser2 = multiprocessing.Process(target=upload)
ser1.start()
ser2.start()
方式二:
from multiprocessing import Process
class MyProcess(Process): #继承Process类
def __init__(self,name):
super(MyProcess,self).__init__()
self.name = name
def run(self):
print('测试%s多进程' % self.name)
if __name__ == '__main__':
process_list = []
for i in range(5): #开启5个子进程执行fun1函数
p = MyProcess('Python') #实例化进程对象
p.start()
process_list.append(p)
for i in process_list:
p.join()
print('结束测试')
3:常用方法中的不同
多进程中的常用方法
join() is equivalent to waiting for the child process to complete, effectively providing a separate detection function for this process. Once the child process completes, the parent process proceeds accordingly.
terminate():不管任务是否完成,立即终止子进程、
daemon=True: 把子进程设置为守护线程,必须在start()之前设置
多线程中的常用方法
1:threading.enumerate():查看线程的数量
2: 互斥锁:在使用互斥锁的同时,锁定的资源越少越好
from threading import Thread,Lock
lock.acquire() #锁定
for n in range(5)
time.sleep(0.1)
print(n)
lock.release() #开启
4:所有子进程结束主进程才会结束 而 多线程不会
5:多进程不共享全局变量 而 多线程共享全局变量
隐藏的不同点:
6: 进程是资源分配的基本单位,线程是CPU执行和调度的基本单位;
7: 通信/同步方式:
-
流程:
-
传输介质:管道通讯机制、FIFO机制、消息队列系统、系统信号、共享内存机制、高级网络接口、流数据传输通道;
-
协调方法:PV信号量系统、进程管理系统
-
线程:
-
同步机制:互斥锁机制、递归锁机制、条件变量机制、信号量机制
-
通信方式:位于同一进程的线程可以直接共享该进程内的内存区域,并因此在这种情况中不存在类似于进程之间用于数据传输的通信机制;相反地,在这种情况下,并不存在类似于进程之间用于数据传输的通信机制。
因此,在这种情况下,并不存在类似于进程之间用于数据传输的通信机制;相反地,在这种情况下,并不存在类似于进程之间用于数据传输的通信机制。
它们之间的交流主要用于实现线程间的同步协调。
8: CPU核心实际运行的是线程;由于其重量较轻于进程,在切换和调度方面所需的计算成本较低;
不同线程在处理共享的数据时必须考虑线程安全问题。由于进程之间的隔离性使得它们各自拥有独立内存空间,在一定程度上提高了系统的安全性。该系统仅允许通过上述提到的IPC协议来进行数据传输。
系统由多个进程构成;每个进程包含了代码段、数据段以及堆空间和栈空间,并且同时拥有操作系统共享部分;每个进程处于等待态、就绪态和运行态三种基本状态。
每个进程都可能拥有多个线程。这些线程之间能够共享相同的资源(如文件描述符、全局变量、堆空间等),而寄存器变量和栈空间则成为每个线程独有的区域。
12: 操作系统中一个进程崩溃不会影响其他进程, 如果一个进程中某个线程崩溃且操作系统对该线程的支持模式为多对一的话, 则会导致当前进程中发生崩溃.
当CPU和系统具备多线程或多核支持时,在多个进程并行运行的同时,并发执行每个进程中的线程组别以最大限度地利用硬件资源以提升系统的整体性能。
相同点
1:多线程与多进程中的参数相同
threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={})
- group: 指定的进程组或线程组(目前仅允许设置为None)
- target: 执行的目标任务名称
- name: 进程或线程的名字
- args: 通过元祖形式向任务传递参数的方式
- kwargs: 以字典形式向任务传递额外参数的形式
- start(): 启动指定的子进程/子线程实例的方法
