Python之多任务

1. 并行

多核CPU处理多任务,操作系统会给cpu的每个内核安排一个执行的软件,多个内核是真正的一起执行软件。这里需要注意多核cpu是并行的执行多任务,始终有多个软件一起执行。

1.1 进程的概念

一个正在运行的程序或者软件就是一个进程,它是操作系统进行资源分配的基本单位,也就是说每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。

进程

注意:

一个程序运行后至少有一个进程,一个进程默认有一个线程,进程里面可以创建多个线程,线程是依附在进程里面的,没有进程就没有线程。

1.2 进程的使用
1.2.1 导包

import multiprocessing

1.2.2 Process类

Process([group [, target [, name [, args [, kwargs]]]]])

group:指定进程组,目前只能使用None
target:执行的目标任务名
name:进程名字 args:以元组方式给执行任务传参
kwargs:以字典方式给执行任务传参

Process创建的实例对象的常用方法:
start():启动子进程实例(创建子进程)
join():等待子进程执行结束
terminate():不管任务是否完成,立即终止子进程

Process创建的实例对象的常用属性:
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
daemon:当前进程是否是守护线程

1.2.3 获取当前进程

获取当前进程对象
multiprocessing.current_process() 对象内有此进程id,name,是否是守护进程等属性

获取当前进程编号
os.getpid() 表示获取当前进程编号
multiprocessing.current_process().pid

获取当前父进程编号
os.getppid() 表示获取当前父进程编号

1.2.4 进程任务传参

Process类执行任务并给任务传参数有两种方式:
args 表示以元组的方式给执行任务传参
kwargs 表示以字典方式给执行任务传参

1.2.5 注意点

进程之间不共享全局变量
主进程会等待所有的子进程执行结束再结束

1.2.3 简单使用

# 1.导包
import multiprocessing
import os


def my_process(name):
    """2.定义一个任务"""
    print(f"This is my process method,It`s name is {name}")
    print(f'The process`s info is {multiprocessing.current_process()}')
    print(f'The process`s id is {os.getpid()} / {multiprocessing.current_process().pid}')
    print(f'The process`s parent id is {os.getppid()}')

if __name__ == '__main__':
    # 创建任务
    p = multiprocessing.Process(group=None,
                                target=my_process,
                                name="my_process",
                                kwargs={'name': 'p1'})
    # 开启
    p.start()

2. 并发

单核CPU,操作系统轮流让各个软件交替执行

2.1 线程的概念

线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度 ,也就是说线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。

线程

2.2 线程的使用
2.2.1 导包

import threading

2.2.2 Thead类

线程类Thread说明
Thead类的属性和方法和Process一致
这些属性和方法的用法、参数传递方式也和进程类Process一致

获取当前线程对象
threading.current_thread()

2.2.3 简单使用

# 1.导包
import threading


def my_thead(name):
    # 2. 定义线程任务
    print(f"this is my thead method,It`s name is {threading.current_thread()}")
    print(f'The thead method name is {name}')


if __name__ == '__main__':
    # 3.创建线程
    t = threading.Thread(group=None,
                     target=my_thead,
                     name='my_first_test_thead',
                     kwargs={'name':'mt'})
    # t.daemon = True  # t.setDaemon(True)
    t.start()

2.2.4 注意点

线程之间执行是无序的
主线程会等待所有的子线程执行结束再结束
线程之间共享全局变量
线程之间共享全局变量数据出现错误问题

2.2.5 线程锁-互斥锁

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

注意:
互斥锁是多个线程一起去抢,抢到锁的线程先执行,没有抢到锁的线程需要等待,等互斥锁使用完释放后,其它等待的线程再去抢这个锁

使用
threading模块中定义了Lock变量,这个变量本质上是一个函数,通过调用这个函数可以获取一把互斥锁。

# 4.创建锁
lock = threading.Lock()

def my_thead(name):
    # 5. 上锁
    lock.acquire()
    print(f"this is my thead method,It`s name is {threading.current_thread()}")
    print(f'The thead method name is {name}')
    # 6. 释放锁
    lock.release()

注意点:
acquire和release方法之间的代码同一时刻只能有一个线程去操作
如果在调用acquire方法的时候 其他线程已经使用了这个互斥锁,那么此时acquire方法会堵塞,直到这个互斥锁释放后才能再次上锁。

# 1.导包
import threading

# 定义全局变量
g_num = 0
# 4.创建锁
lock = threading.Lock()

def sum():
    # 5. 上锁
    lock.acquire()
    # 2. 累加
    for i in range(10000):
        global g_num  # 申明全局变量
        print(f'{threading.current_thread().name} excuse add one to g_num')
        g_num += 1
    else:
        print(f'{threading.current_thread().name} add result is {g_num}')
    # 6. 释放锁
    lock.release()

if __name__ == '__main__':
    # 3.创建线程
    t1 = threading.Thread(group=None,
                     target=sum,
                     name='t1')

    t2 = threading.Thread(group=None,
                          target=sum,
                          name='t2')
    t1.start()
    t2.start()

3. 进程与线程的对比

3.1 关系对比

线程是依附在进程里面的,没有进程就没有线程。
一个进程默认提供一条线程,进程可以创建多个线程。

3.2 区别对比

进程之间不共享全局变量
线程之间共享全局变量,但是要注意资源竞争的问题,解决办法: 互斥锁或者线程同步
创建进程的资源开销要比创建线程的资源开销要大
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
线程不能够独立执行,必须依存在进程中
多进程开发比单进程多线程开发稳定性要强

3.3 优缺点对比

进程优缺点:
优点:可以用多核
缺点:资源开销大

线程优缺点:
优点:资源开销小
缺点:不能使用多核

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值