人工智能 -多任务编程、进程、线程介绍

news2025/4/27 9:04:13

目录

    • 1, 多任务的概念
    • 2,进程
      • 2.1进程的介绍
      • 2.2多进程完成多任务
      • 2.3进程执行带有参数的任务
      • 2.4获取进程编号
      • 2.5进程间不共享全局变量
      • 2.6主进程和子进程的结束顺序
    • 3、线程
      • 3.1多线程完成多任务
      • 3.2线程执行带有参数的任务
      • 3.3主线程和子线程的结束顺序
      • 3.4线程中的执行顺序
      • 3.5线程间共享全局变量
      • 3.6线程间共享全局变量数据出现错误问题
      • 3.7 互斥锁
      • 3.8死锁
      • 3.9进程和线程的对比

下载时多个一起下载 --多任务
多任务的最大好处:充分利用CPU资源,提高程序的执行效率

1, 多任务的概念

多任务是指同一时间内执行多个任务
两种表现形式:并发 ,并行

  • 并发:一段时间内交替去执行多个任务
    并发:任务数量大于CPU的核心数
  • 并行:在一段时间内真正的同时一起执行多个任务
    并行:任务数量小于等于CPU的核心数

2,进程

2.1进程的介绍

进程是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位,通俗理解:一个正在运行的程序就是一个进程。
例如:正在运行的qq,微信等,
微信在没有运行时,只是一个软件,当运行后,会变成占cpu资源,内存资源的进程

进程是资源分配的最小单位
多进程是python程序中实现多任务的一种方式,使用多进程可以大大提高程序的执行效率

2.2多进程完成多任务

进程的创建步骤:
1,导入进程包
import multiprocessing
2,通过进程类创建进程对象
进程对象 = multiprocessing.Process()
3,启动进程执行任务
进程对象.start()

进程对象 = multiprocessing.Process(target=任务名)
在这里插入图片描述

#单任务:先coding再music
import time
#编写代码
def coding():
	for i in range(3):
		print('coding...')
		time.sleep(0.2) #停顿0.2秒

#听音乐
def music():
	for i in range(3):
		print('music...')
		time.sleep(0.2) #停顿0.2秒
		
if __name__ =='__main__':
	coding()
	music()

输出:先打印三次coding后再打印三次music
在这里插入图片描述

多进程:三步。进程明显变快

#多进程
import multiprocessing
import time
#编写代码
def coding():
	for i in range(3):
		print('coding...')
		time.sleep(0.2) #停顿0.2秒

#听音乐
def music():
	for i in range(3):
		print('music...')
		time.sleep(0.2) #停顿0.2秒
		
if __name__ =='__main__':
	#通过进程类创建进程对象
	coding_process = multiprocessing.Process(target=coding)
	music_process = multiprocessing.Process(target=music)
	#启动进程
	coding_process.start()
	music_process.start()

2.3进程执行带有参数的任务

在这里插入图片描述

import multiprocessing
import time
#编写代码
def coding(num):
	for i in range(num,name):
		print(name)
		print('coding...')
		time.sleep(0.2) #停顿0.2秒

#听音乐
def music(count):
	for i in range(count):
		print('music...')
		time.sleep(0.2) #停顿0.2秒
		
if __name__ =='__main__':
	#通过进程类创建进程对象
	coding_process = multiprocessing.Process(target=coding,args=(3,'传智'))
	#传参args=(3,)元组
	music_process = multiprocessing.Process(target=music,kwargs={'count':2})
	#启动进程
	coding_process.start()
	music_process.start()

传参两种方式:
1,元组方式传参。顺序要保持一致
2,字典方式传参。key与参数名保持一致

2.4获取进程编号

进程数量越来越多,进行编号来进行管理

获取当前进程标号:getpid()方法
获取当前父进程编号:getppid()方法
在这里插入图片描述

import multiprocessing
import time
import os
def coding():
	print('coding>>>%d' % os.getpid())
	print('coding父进程>>>%d' % os.getppid())
	for i in range(3):
		print('coding...')
		time.sleep(0.2) #停顿0.2秒

#听音乐
def music():
	print('music>>>%d' % os.getpid())
	print('music父进程>>>%d' % os.getppid())
	for i in range(3):
		print('music...')
		time.sleep(0.2) #停顿0.2秒
		
if __name__ =='__main__':
	print('主进程>>>%d' % os.getpid())
	#通过进程类创建进程对象
	coding_process = multiprocessing.Process(target=coding)
	music_process = multiprocessing.Process(target=music)
	#启动进程
	coding_process.start()
	music_process.start()

2.5进程间不共享全局变量

进程间是不共享全局变量的
创建一个子进程就是把主进程的资源进行拷贝产生了一个新的进程,而主程序和子程序之间是相互独立的

import multiprocessing
#全局变量
my_list = []
#写入数据
def write_data():
	for i in range(3):
		my_list.append(i)
		print('add:',i)
	print(my_list)

#读取数据
def read_data():
	print(my_list)
	
if __name__ =='__main__':
	#创建写入数据进程
	write_process = multiprocessing.Process(target=write_data)
	#创建读取数据进程
	read_process = multiprocessing.Process(target=read_data)
	#启动
	write_process.start()
	read_process.start()

写入进程中my_list不为空,但读入进程中的my_list还为空

2.6主进程和子进程的结束顺序

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

import multiprocessing
import time
#工作函数
def work():
	for i in range(10):
		print('工作中。。')
		time.sleep(0.2)
		
if __name__ =='__main__':
	#创建写入数据进程
	work_process = multiprocessing.Process(target=work)
	work_process.start()
	#延时1秒
	time.sleep(1)
	print('主进程执行完毕')

在这里插入图片描述
虽然输出如此,但是还是在子进程结束后,主进程才结束
如何才能确保主进程最后执行:法一:守护主进程,法二:手动结束子进程

import multiprocessing
import time
#工作函数
def work():
	for i in range(10):
		print('工作中。。')
		time.sleep(0.2)
		
if __name__ =='__main__':
	#创建写入数据进程
	work_process = multiprocessing.Process(target=work)
	#work_process.daemon = True  ##守护主进程
	work_process.start()
	#延时1秒
	time.sleep(1)
	#work_process.terminate() #手动结束子进程
	print('主进程执行完毕')

在这里插入图片描述

3、线程

在这里插入图片描述
线程是程序执行的最小单位
同属一个进程的多个线程共享进程所拥有的全部资源

3.1多线程完成多任务

线程的创建步骤:
1,导入线程模块 import threading
2,通过线程类创建线程对象 线程对象 = ‘threading.Thread(target=任务名)’
3,启动线程执行任务 线程对象.start()
在这里插入图片描述

import threading
import time
#编写代码
def coding():
	for i in range(3):
		print('coding...')
		time.sleep(0.2) #停顿0.2秒

#听音乐
def music():
	for i in range(3):
		print('music...')
		time.sleep(0.2) #停顿0.2秒
		
if __name__ =='__main__':
	#创建子线程
	coding_process = threading.Thread(target=coding)
	music_process = threading.Thread(target=music)
	#启动子线程
	coding_thread.start()
	music_thread.start()

输出:两个同时在运行,且时间更少
在这里插入图片描述

3.2线程执行带有参数的任务

在这里插入图片描述

import multiprocessing
import time
#编写代码
def coding(num):
	for i in range(num,name):
		print(name)
		print('coding...')
		time.sleep(0.2) #停顿0.2秒

#听音乐
def music(count):
	for i in range(count):
		print('music...')
		time.sleep(0.2) #停顿0.2秒
		
if __name__ =='__main__':
	#通过进程类创建进程对象
	coding_thread = threading.Thread(target=coding,args=(3,'传智'))
	#传参args=(3,)元组
	music_thread = threading.Thread(target=music,kwargs={'count':2})
	#启动进程
	coding_thread.start()
	music_thread.start()

3.3主线程和子线程的结束顺序

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

import threading
import time
#工作函数
def work():
	for i in range(10):
		print('工作中。。')
		time.sleep(0.2)
		
if __name__ =='__main__':
	#创建写入数据进程
	work_process = threading.Thread(target=work)
	work_process.start()
	#延时1秒
	time.sleep(1)
	print('主进程执行完毕')

在这里插入图片描述
输出表明:主线程完毕后,子线程还在执行
解决方法:1,参数方式设置守护主线程 2,子线程自动销毁

import threading
import time
#工作函数
def work():
	for i in range(10):
		print('工作中。。')
		time.sleep(0.2)
		
if __name__ =='__main__':
	#创建写入数据进程
	#方式1:参数方式设置守护主线程daemon=True
	#work_process = threading.Thread(target=work,daemon=True)
	work_process = threading.Thread(target=work)
	#方式2:
	#work_thread.setDaemon(True)
	work_process.start()
	#延时1秒
	time.sleep(1)
	print('主进程执行完毕')

在这里插入图片描述
这样设置的目的:让主线程退出后子线程销毁,不让主线程再等待子线程去执行

3.4线程中的执行顺序

线程之间执行是无序的,是由CPU调度决定某个线程先执行的。并非先创建的先执行

3.5线程间共享全局变量

多个线程是在同一个进程中,多个线程使用的资源是同一个进程中的资源,因此多线程间是共享全局变量。

import multiprocessing
#全局变量
my_list = []
#写入数据
def write_data():
	for i in range(3):
		my_list.append(i)
		print('add:',i)
	print('write:',my_list)

#读取数据
def read_data():
	print('read',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)
	read_thread.start()

在这里插入图片描述
读取和写入的是一样的,说明线程间共享全局变量

3.6线程间共享全局变量数据出现错误问题

#全局变量
g_num = 0
#对g_num进行加操作
def sum_num1():
	for i in range(1000000):
		global g_num
		g_num+=1
	print('g_num1:',g_num)

#对g_num进行加操作
def sum_num2():
	for i in range(1000000):
		global g_num
		g_num+=1
	print('g_num2:',g_num)

if __name__ =='__main__':
	sum1_thread = threading.Thread(target=sum_num1)
	sum2_thread = threading.Thread(target=sum_num2)
	sum1_thread.start()
	sum2_thread.start()

在这里插入图片描述
输出结果混乱,不是,g_num1:1000000;g_num2:2000000
解决方法:
使用线程同步:保证同一时刻只能有一个线程去操作全局变量

多线程同时操作全局变量可能会导致数据出现错误问题,可以使用线程同步方式来解决这个问题(互斥锁)

3.7 互斥锁

互斥锁:对共享数据进行锁定,保证同一时刻只有一个线程去操作
互斥锁是多个线程一起去抢,抢到锁的线程先执行,没有抢到锁的线程先等等,等锁使用完释放后,再其余线程去抢这个锁
步骤:
1,互斥锁创建
mutex = threading.Lock()
2,上锁
mutex.acquire()
3,释放锁
mutex.release()

#全局变量
g_num = 0
#对g_num进行加操作
def sum_num1():
	#上锁
	mutex.acquire()
	for i in range(1000000):
		global g_num
		g_num+=1
	#解锁
	mutex.release()
	print('g_num1:',g_num)

#对g_num进行加操作
def sum_num2():
	#上锁
	mutex.acquire()
	for i in range(1000000):
		global g_num
		g_num+=1
	#解锁
	mutex.release()
	print('g_num2:',g_num)

if __name__ =='__main__':
	#创建锁
	mutex = threading.Lock()
	sum1_thread = threading.Thread(target=sum_num1)
	sum2_thread = threading.Thread(target=sum_num2)
	sum1_thread.start()
	sum2_thread.start()

在这里插入图片描述
输出结果正常了

3.8死锁

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

#全局变量
g_num = 0
#对g_num进行加操作
def sum_num1():
	#上锁
	print('sum_num1...')
	mutex.acquire()
	for i in range(1000000):
		global g_num
		g_num+=1
	
	print('g_num1:',g_num)

#对g_num进行加操作
def sum_num2():
	#上锁
	print('sum_num2...')
	mutex.acquire()
	for i in range(1000000):
		global g_num
		g_num+=1
	
	print('g_num2:',g_num)

if __name__ =='__main__':
	#创建锁
	mutex = threading.Lock()
	sum1_thread = threading.Thread(target=sum_num1)
	sum2_thread = threading.Thread(target=sum_num2)
	sum1_thread.start()
	sum2_thread.start()

在这里插入图片描述
sum_num1和sum_num2没有释放锁的步骤,导致死锁

3.9进程和线程的对比

关系对比:

  1. 线程是依附在进程里面的,没有进程就没有线程
  2. 一个进程默认提供一条主线程,但可以提供多个子线程

进程和线程的区别对比:
在这里插入图片描述
进程优缺点:优:可以多核(即可以同时运行QQ和微信,此时是并行) 缺:资源开销大

线程优缺点:优:资源开销大;缺:不能使用多核(不能并行,只能并发,排队等待)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

连续子数组的最大和(从暴力理解到DP)

连续子数组的最大和题目思路暴力解题思路画出矩阵进行分析确定转移方程DP代码题目 思路 从leetcode上看到的题解,突然恍然大悟,之前不容易理解转移方程终于理解了,这个思路真的对新手很友好,现在出一个C版本,而且&…

谷歌出品,数据集搜索引擎上线了!

文 | 小戏记得在刚入门 ML 时,希望找到一个关于特定领域下的数据集,涉世未深的我在中文互联网不断搜索,可每每点进链接出来的都是某 SDN 下载的高价勒索。用惯了直接从老师同学那里讨来的数据集的我第一次感受到了“寻找数据集”这样一个简单…

【并查集】实现思路及例题

一、应用场景 用于处理不相交集合的合并和查询问题 示例: n 个元素(分属不同的的 n 个集合),进行两种操作: 并 —— 给出两个元素的关系,合并两个集合查 —— 查询两个元素是否在同一个集合 二、并查集…

「数据密集型系统搭建」原理篇|用什么方式存储数据最合适

本篇来聊聊数据存储的内容,看看程序世界里数据是以什么形式存在的?为了描述数据并把它们和这个现实世界关联起来我们一般都是如何去进行表达的?最后通过我们习惯的表达方式再结合数据结构是如何存储下来的? 在进行技术方案设计的时…

分享102个PHP源码,总有一款适合您

PHP源码 分享117个PHP源码,总有一款适合您 PHP源码下载链接:https://pan.baidu.com/s/1Ike0x99BcMfZPy6tFSpM9w?pwdzqem 提取码:zqem import os from time import sleepimport requests from bs4 import BeautifulSoup from docx import D…

Linux 系统Bash的常用功能

了解了基本的Linux文件文件系统的概念后,我们将更深入的了解一下Linux的其他方面的内容,那就是我们所使用的用户接口,也就是大家常听到的 Shell ,是一种Linux的命令接口,在 Linux 的世界中,默认使用的是 GNU 开发出来的 shell ,称为 BASH Shell,简单来说,我们之前使用的几个命令…

10.JS笔记-对象

1、什么是对象 对象是一个具体的事物,在js中,对象是一组无序的属性和方法的集合 属性:事物的特征 方法:事物的行为 2、创建对象 利用字面量创建对象利用new Object创建对象利用构造函数创建对象 2.1 变量、属性和方法、函数的…

人工智能的核心技术是什么?

(本文阅读时间:5分钟)人工智能的核心技术是它的算法被广泛认可的「算法」专业定义是:算法是模型分析的一组可行的,确定的,有穷的规则。基于规则的人工智能上个世纪六七十年代出现的早期人工智能系统都是基于…

VueJs中如何自定义hooks(组合式)函数

前言在Vue当中,一个非常重要的功能就是组件的复用,编写Vue组件,更多的也是在拼装组件,将页面的各个功能进行模块化便于维护和管理,而在项目里,有些页面中的组件的逻辑功能是一样的,如果没有进行功能逻辑的复用,那么每个页面都需要重复的写一遍在Vue当中各个组件是保持独立的,如…

一份职业游戏3D建模师日常工作流程列表,看完不信还有人说建模门槛低

随着游戏行业的发展,越来越多的人开始对这个行业感兴趣,因此有很多的小伙伴梦想成为一个游戏模型师,成为游戏行业里的一员。但是很多人都对这个工作具体是做什么的并不是很了解,下面,我们就来说说游戏模型师的主要工作…

Word处理控件Aspose.Words功能演示:使用 C# 将 DOCX 转换为 HTML

Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外, Aspose API支持流行文件格式处…

Javascript:Class构造函数

为什么需要class 在其他语言中class已经是一个早就被实现的功能,在JavaScript中一直到ES6被实现。在class没有实现之前我们是这样写的(如下代码) function Person(name,sex){this.name this.sex } Person.prototype.sayfunction(){alert(h…

金融类的APP该如何进行ASA推广

移动理财成为新金融的主流,在如今,金融机构都在争相推出自己的移动理财产品,那今天柚鸥ASO就来给大家讲一下,金融类的APP在进行ASA前的一些注意事项。 APP进行ASA前的开户有两种: 自主开户(1,…

检测物理内存容量

文章目录前言前置知识BIOS 中断 0x15 子功能 0xe820 获取内存代码说明实验操作前言 本博客记录《操作系统真象还原》第五章实验操作~ 实验环境:ubuntu18.04VMware , Bochs下载安装 实验内容:三种检测内存的方法。 实验原理: …

volaile关键字详解!

文章目录什么是volatile ?volatile三大特性volatile如何使用volatile保证可见性volatile不保证原子性volatile禁止指令重排volatile总结什么是volatile ? volatile是一个Java关键字volatile是Java虚拟机提供的轻量级的同步机制 volatile三大特性 保证…

【服务器搭建个人网站】教程五:手把手教你怎样进行公安备案 快来学~

前言 购买一台服务器,再来个域名,搭建一个自己的个人博客网站,把一些教程、源码、想要分享的好玩的放到网站上,供小伙伴学习玩耍使用。我把这个过程记录下来,想要尝试的小伙伴,可以按照步骤,自己…

【Qt】将QtDesigner生成的.ui文件转化为.h头文件

【Qt】将QtDesigner生成的.ui文件转化为.h头文件1、背景2、实例3、附件1、背景 操作系统:windows10专业版。 Qt版本:qt-opensource-windows-x86-msvc2013_64-5.7.1.exe 博主的Qt安装目录:E:\E01_cppIDE\E01_qt\install 并将安装后的bin目录…

校园wifi网页认证登录入口

一、校园WIFI自助服务简介在我校校园网认证业务中,教职工校园通行证账号支持最大3个终端同时在线,如果超出最大在线数,最后上线的终端会把第一个上线的终端踢下线,导致终端经常掉线,需要重新登录才可上网。那么&#x…

【Linux】基础:基础IO

【Linux】基础:基础IO 摘要:本文基础IO的内容将从过往熟悉的C语言文件操作出发,引申指系统调用的文件操作,再进一步深化为对于进程管理的文件进行介绍,从而了解文件描述符的概念和管理方式,其中还会介绍其运…

2022 IoTDB Summit:京东刘刚《Apache IoTDB 在京东万物互联场景中的应用》

12 月 3 日、4日,2022 Apache IoTDB 物联网生态大会在线上圆满落幕。大会上发布 Apache IoTDB 的分布式 1.0 版本,并分享 Apache IoTDB 实现的数据管理技术与物联网场景实践案例,深入探讨了 Apache IoTDB 与物联网企业如何共建活跃生态&#…