了解多进程和多线程的区别——【Python】代码实现

一、多任务

        并行:同时执行多个任务
        并发:交替执行任务

二、进程

1、概述:是 操作系统CPU 资源分配 的最小单位


2、多进程作用:提高 执行效率


3、创建进程

# 导包
import multiprocessing

子进程对象 = multiprocessing.Process(target=...,name=...,args=...,kwargs=...)
        
进程对象.start( )

4、进程编号:唯一标识一个进程

# 获取当前进程
os.getpid()
mp.current_process().pid

# 获取父进程
os.getppid()

5、注意点

        进程之间 不共享 全局变量(进程间数据是 相互隔离的)

        主进程会等待 所有子进程 执行结束再结束

6、例题

需求:请使用多进程形式完成:一边写代码、一边听音乐。

# 1、导包
import multiprocessing, time

# 2、定义 写代码 函数
def coding():
	for i in range(5):
		print(f'敲了{i}行代码')
		time.sleep(0.5)        # 休眠一下,否则数据太少,体现不出结果

# 3、定义 听音乐 函数
def music():
	for i in range(5):
		print(f'听了{i}首音乐')
		time.sleep(0.5)

# 4、使用多进程完成;
if __name__ == '__main__':
	p1 = multiprocessing.Process(target = coding)    # 调用multiprocessing
	p2 = multiprocessing.Process(target = music)

	p1.start()    # 运行子进程
	p2.start()


三、线程


1、概述:依附于进程,是CPU调度的基本单元


2、CPU调度资源策略

        抢占式调度:谁抢到谁执行,可能数据乱序
        均分时间片:每个线程获取的CPU时间都是固定的,一致的

3、实现格式

# 1、导包
import threading

子线程对象 = Thread(target=...,name=...,args=...,kwargs=...)

# 2、获取当前线程
线程对象=threading.current_thread()

4、特点

        1. 执行顺序:无序
        2. 主线程会 等待 所有子线程 执行结束再结束
        3. 线程间 数据可以共享

5、例题

需求:请使用多线形式完成:一边写代码、一边听音乐。

# 1、导包
import threading, time
# 2、定义 编码 函数
def coding():
	for i in range(5):
		print(f'敲了{i}行代码')
		time.sleep(0.5)
# 3、定义 听音乐 函数
def music():
	for i in range(5):
		print(f'听了{i}首音乐')
		time.sleep(0.5)

# 4、在 main函数中测试
if __name__ == '__main__':
	t1 = threading.Thread(target=coding)
	t2 = threading.Thread(target=music)
	t3 = threading.Thread(target=chat)

	t1.start()
	t2.start()
	t3.start()

6、让主进程 结束时,子进程 立即结束的2个方式

        1. 守护进程 or 线程
                当非守护进程结束时,守护进程立即结束
                设置:子进程.daemon=True

举个例子吧~

import threading, time

def work():
    for i in range(5):
        print(f'工作{i}小时')
        time.sleep(0.3)

if __name__ == '__main__':
    t1 = threading.Thread(target=work, daemon=True)    # 守护线程
    t1.start()

    time.sleep(1)
    print('主线程结束')

        2. 手动结束:子进程.terminate()
                僵尸进程,不建议写,虽然关闭但依然占用资源
                子线程不能手动结束


7、互斥锁

        1. 作用:对共享数据进行锁定,保证同一时刻只有一个线程去操作

        2. 流程:创建锁:mutex = threading.Lock( )
                       加锁:mutex.acquire( )
                       释放锁:mutex.release( )

        3. 线程同步:也叫线程安全,即同一时刻,只有1个线程对资源有操作权,通过加锁实现

# 1. 导包
import threading, time

# 创建(互斥)锁
mutex = threading.Lock()

# 2. 定义全局变量
my_num = 0

# 3. 定义函数, 对 my_num累加 100W次
def add_sum1():
    # 加锁
    mutex.acquire()

    for i in range(1000000):
        global my_num    # 修饰为全局变量.
        my_num += 1

    # 解锁
    mutex.release()

    print(f'add_sum1函数: {my_num}')       # 1000000

# 4. 定义函数, 对 my_num累加 100W次
def add_sum2():
    # time.sleep(3)
    # 加锁
    mutex.acquire()

    for i in range(1000000):
        global my_num    # 修饰为全局变量.
        my_num += 1

    # 解锁
    mutex.release()
    print(f'add_sum2函数: {my_num}')       # 2000000

# 主线程
if __name__ == '__main__':
    # 5. 创建线程
    t1 = threading.Thread(target=add_sum1)
    t2 = threading.Thread(target=add_sum2)

    # 6. 开启线程.
    t1.start()
    t2.start()

8、死锁:一直等待对方释放锁的情景

# 1、导包
import threading, time
# 2、创建锁
mutex = threading.Lock()
# 3、定义 编码 函数
def coding():
	mutex.acquire()
	for i in range(5):
		print(f'敲了{i}行代码')
		time.sleep(0.5)
	# mutex.release()        # 没有释放锁
# 4、定义 听音乐 函数
def music():
	mutex.acquire()
	for i in range(5):
		print(f'听了{i}首音乐')
		time.sleep(0.5)
	# mutex.release()        # 没有释放锁

# 5、主线程
if __name__ == '__main__':
    # 创建线程
	t1 = threading.Thread(target=coding)
	t2 = threading.Thread(target=music)
    # 开启线程
	t1.start()
	t2.start()

四、进程和线程的对比

        1. 进程可以多核,资源开销大;线程资源开销小,不可以多核
        2. 进程之间 不共享 全局变量,线程 共享
        3. 进程是操作系统 资源分配 的最小单位,线程是 CPU调度 的基本单元
        4. Python中 多进程开发 比 单进程多线程开发 稳定性要强

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值