Python进阶---多任务编程

简介: Python进阶---多任务编程

一、多任务的介绍

1、多任务的概念


多任务是指在同一时间内执行多个任务,例如: 现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。


2、多任务的执行方式


并发:对于单核cpu处理多任务,操作系统轮流让各个软件交替执行,单核cpu是并发的执行多任务的。

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

二、进程

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


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

1、多进程的使用

1 导入进程包
 
#导入进程包
import multiprocessing
 
 
2. Process进程类的说明
 
Process([group [, target [, name [, args [, kwargs]]]]])
 
group:指定进程组,目前只能使用None
target:执行的目标任务名
name:进程名字
args:以元组方式给执行任务传参
kwargs:以字典方式给执行任务传参
Process创建的实例对象的常用方法:
 
start():启动子进程实例(创建子进程)
join():等待子进程执行结束
terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性:
 
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数

2、获取进程编号

获取进程编号的目的是验证主进程和子进程的关系,可以得知子进程是由那个主进程创建出来的。


获取进程编号的两种操作


获取当前进程编号:os.getpid() 表示获取当前进程编号

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

获取进程编号可以查看父子进程的关系

3、进程执行带有参数的任务

import multiprocessing
import time
 
 
def sing(num, name):
    for i in range(num):
        time.sleep(1)
        print("唱歌")
        time.sleep(1)
        print(name)
 
 
def dance(num, name):
    for i in range(num):
        time.sleep(1)
        print("跳舞")
        time.sleep(1)
        print(name)
 
 
if __name__ == '__main__':
    # 给进程执行的任务传参
    # 通过args去传参 : 元组的形式传参
    sing_process = multiprocessing.Process(target=sing, args=(3, "老王"))
    # 通过kwargs传参 : 字典的形式传参
    # 字典里的key值必须和函数的形参一致
    dance_process = multiprocessing.Process(target=dance, kwargs={"num": 3, "name": "老李"})
 
    sing_process.start()
    dance_process.start()

4、进程的注意点

       进程之间不共享全局变量

import multiprocessing
import time
 
# 定义全局变量
g_list = list()
 
 
# 添加数据的任务
def add_data():
    for i in range(5):
        g_list.append(i)
        print("add:", i)
        time.sleep(0.2)
 
    # 代码执行到此,说明数据添加完成
    print("add_data:", g_list)
 
 
def read_data():
    print("read_data", g_list)
 
 
if __name__ == '__main__':
    # 创建添加数据的子进程
    add_data_process = multiprocessing.Process(target=add_data)
    # 创建读取数据的子进程
    read_data_process = multiprocessing.Process(target=read_data)
 
    # 启动子进程执行对应的任务
    add_data_process.start()
    # 主进程等待添加数据的子进程执行完成以后程序再继续往下执行,读取数据
    add_data_process.join()
    read_data_process.start()
 
    print("main:", g_list)
 
    # 总结: 多进程之间不共享全局变量

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

import multiprocessing
import time
 
 
# 定义进程所需要执行的任务
def task():
    for i in range(10):
        print("任务执行中...")
        time.sleep(0.2)
 
if __name__ == '__main__':
    # 创建子进程
    sub_process = multiprocessing.Process(target=task)
    sub_process.start()
 
    # 主进程延时0.5秒钟
    time.sleep(0.5)
    print("over")
    exit()
 
    # 总结: 主进程会等待所有的子进程执行完成以后程序再退出
3.

三、线程

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

1、多线程的使用

1. 导入线程模块
 
#导入线程模块
import threading
 
2. 线程类Thread参数说明
 
Thread([group [, target [, name [, args [, kwargs]]]]])
 
group: 线程组,目前只能使用None
target: 执行的目标任务名
args: 以元组的方式给执行任务传参
kwargs: 以字典方式给执行任务传参
name: 线程名,一般不用设置
 
3. 启动线程
启动线程使用start方法

2、线程执行带有参数的任务

import time
# 导入多线程的模块
import threading
 
 
def sing(num, name):
    for _ in range(num):
        time.sleep(0.5)
        print(name)
 
 
def dance(num, name):
    for _ in range(num):
        time.sleep(0.5)
        print(name)
 
 
if __name__ == '__main__':
    # Process: 创建进程
    # 参数1: target 进程要执行的任务 ==> 任务往往用函数名来表示
    sing_thread = threading.Thread(target=sing, args=(3, "老王"))
    dance_thread = threading.Thread(target=dance, kwargs={"num": 3, "name": "老李"})
    # 启动进程
    sing_thread.start()
    dance_thread.start()

3、线程的注意点

  1. 线程之间执行是无序的
import threading
import time
 
 
def task():
    time.sleep(1)
    print("当前线程:", threading.current_thread().name)
 
 
if __name__ == '__main__':
 
   for _ in range(5):
       sub_thread = threading.Thread(target=task)
       sub_thread.start()
  1. 主线程会等待所有的子线程执行结束再结束
import threading
import time
 
 
# 测试主线程是否会等待子线程执行完成以后程序再退出
def show_info():
    for i in range(5):
        print("test:", i)
        time.sleep(0.5)
 
 
if __name__ == '__main__':
    sub_thread = threading.Thread(target=show_info)
    sub_thread.start()
 
    # 主线程延时1秒
    time.sleep(1)
    print("over")
  1. 线程之间共享全局变量
import threading
import time
 
 
# 定义全局变量
my_list = list()
 
# 写入数据任务
def write_data():
    for i in range(5):
        my_list.append(i)
        time.sleep(0.1)
    print("write_data:", my_list)
 
 
# 读取数据任务
def read_data():
    print("read_data:", my_list)
 
 
if __name__ == '__main__':
    # 创建写入数据的线程
    write_thread = threading.Thread(target=write_data)
    # 创建读取数据的线程
    read_thread = threading.Thread(target=read_data)
 
    write_thread.start()
    # 延时
    # time.sleep(1)
    # 主线程等待写入线程执行完成以后代码在继续往下执行
    write_thread.join()
    print("开始读取数据啦")
    read_thread.start()
  1. 线程之间共享全局变量数据出现错误问题
import threading
 
# 定义全局变量
g_num = 0
 
 
# 循环一次给全局变量加1
def sum_num1():
    for i in range(1000000):
        global g_num
        g_num += 1
 
    print("sum1:", g_num)
 
 
# 循环一次给全局变量加1
def sum_num2():
    for i in range(1000000):
        global g_num
        g_num += 1
    print("sum2:", g_num)
 
 
if __name__ == '__main__':
    # 创建两个线程
    first_thread = threading.Thread(target=sum_num1)
    second_thread = threading.Thread(target=sum_num2)
 
    # 启动线程
    first_thread.start()
    # 启动线程
    second_thread.start()

四、进程和线程对比

  • 进程和线程都是完成多任务的一种方式
  • 多进程要比多线程消耗的资源多,但是多进程开发比单进程多线程开发稳定性要强,某个进程挂掉不会影响其它进程。
  • 多进程可以使用cpu的多核运行,多线程可以共享全局变量。
  • 线程不能单独执行必须依附在进程里面

<end>

目录
相关文章
|
8天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
8天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
8天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
2天前
|
存储 人工智能 数据挖掘
Python编程入门:打造你的第一个程序
本文旨在为初学者提供Python编程的初步指导,通过介绍Python语言的基础概念、开发环境的搭建以及一个简单的代码示例,帮助读者快速入门。文章将引导你理解编程思维,学会如何编写、运行和调试Python代码,从而开启编程之旅。
22 2
|
2天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
|
3天前
|
存储 Python
Python编程入门:理解基础语法与编写简单程序
本文旨在为初学者提供一个关于如何开始使用Python编程语言的指南。我们将从安装Python环境开始,逐步介绍变量、数据类型、控制结构、函数和模块等基本概念。通过实例演示和练习,读者将学会如何编写简单的Python程序,并了解如何解决常见的编程问题。文章最后将提供一些资源,以供进一步学习和实践。
11 1
|
10天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
5天前
|
存储 网络协议 IDE
从零起步学习Python编程
从零起步学习Python编程
|
9天前
|
机器学习/深度学习 存储 算法
探索Python编程:从基础到高级应用
【10月更文挑战第38天】本文旨在引导读者从Python的基础知识出发,逐渐深入到高级编程概念。通过简明的语言和实际代码示例,我们将一起探索这门语言的魅力和潜力,理解它如何帮助解决现实问题,并启发我们思考编程在现代社会中的作用和意义。
|
10天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
下一篇
无影云桌面