Python知识点18---进程和线程

提前说一点:如果你是专注于Python开发,那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了,而如果你和作者一样只是操作其他技术的Python API那就足够了。

首先我要给大家说一下进程和线程有什么区别,进程包含着线程,我们都打开过Windows的任务管理器,我们在其中看到的各种任务,每一个任务,就是一个进程,在这个进程下,有着多个线程组成了这个进程,我在网上找了一个更贴切的解释
在这里插入图片描述


Python允许你的任务是多进程执行的,在使用多进程的时候你需要注意两点

1、进程之间不共享资源,因为他们相互之间是独立的
2、主进程的结束,要等到所有子进程全部结束,这一点大家或许有疑惑,其实我们在运行一个程序时,一开始直接运行的进程就是主进程,也就是说主进程有且只有一个,而子进程就是我们在主进程中书写代码的方式开启的其他进程
3、进程之间执行是无序的

那么问题来了,多进程的应用在哪里?其实进程在开发中只有一个作用,就是充分利用CPU资源执行多任务运行,提高执行效率,打个比方说,某一个程序有多个功能,但是我们在平常开发的时候,只能是多个功能挨个执行,这个时候使用多进程可以让这些功能一起执行,就比如我们的系统就是一个多进程的东西,所以多进程他是在所要执行的任务之间没有必要关联,任务之间相对独立的情况下使用的一种提升程序效率的开发手段

对于进程,我们有两种运行模式,并发并行,现在很多时候说的多进程都是主并行副并发,比如现在的普遍的8核CPU,它其实相当于只有8个人干活,这8个人如果总任务数小于8那就是并行,多余8个那就是8个人在力所能及的范围内并发的工作


多进程在使用的时候,使用方式如下

import multiprocessingdef p():for i in range(5) :print(i)if __name__ == '__main__' :a = multiprocessing.Process(target=p)a.start()for i in range(5) :print(str(i) + '主进程')结果:
0主进程
1主进程
2主进程
3主进程
4主进程
0
1
2
3
4

在不同系统上使用python的多进程的时候,有一个巨大的坑!!!!!如果你的程序运行在了Windows上,那么你创建子进程的操作一定要和我一样写在python的主方法里面,因为Windows上运行的时候,由于系统比较死板,它不会如linux那样直接开始运行Python解析器,它必须要先创建一个依托于Python的进程启动解析器,才去执行你的Python代码,这就导致,你如果不在主方法里面写,它会导致代码执行错乱,把开始子进程当做普通代码加载,无限次递归调用创建子进程方法,最后导致子进程创建失败


其次介绍一下Process这个类,该类有5个参数

group:指定进程组,这个参数不要设置,让它默认None就行,这个是Python保留的一个参数,当前3.0版本,你设置其他参数就会报错
target:进程要执行的任务,值是一个函数名,必备参数
name:进程名称,可以不设置
args:如果进程执行的任务需要传参,则以元组的形式传递
kwargs:也是用来传参的,不过是以字典的形式

Process常用方法有三个

start() 启动进程
join() 等待子进程执行完毕
terminate() 无论子进程的任务是否执行完毕,立马结束子进程Process

你如果想获取执行代码的进程的编号,那么需要使用os模块

import multiprocessing
import osdef p():print('当前子进程id:',os.getpid())if __name__ == '__main__' :a = multiprocessing.Process(target=p)a.start()print('当前主进程id:',os.getpid())结果:
当前主进程id9892
当前子进程id10220

当然你如果想看一下,当前执行代码的是那个进程,它的名字,就使用如下的方法

import multiprocessing
import osdef p():print('当前子进程id:',os.getpid(),'进程名字为:',multiprocessing.current_process())if __name__ == '__main__' :a = multiprocessing.Process(target=p)a.start()print('当前主进程id:',os.getpid(),'进程名字为:',multiprocessing.current_process())结果:
当前主进程id: 12432 进程名字为: <_MainProcess name='MainProcess' parent=None started>
当前子进程id: 7092 进程名字为: <Process name='Process-1' parent=12432 started>

当然os模块,还可以杀死进程

import multiprocessing
import osdef p():os.kill(os.getpid(),9) #9代表执行力度,9表示立马杀死print('当前子进程id:',os.getpid(),'进程名字为:',multiprocessing.current_process())if __name__ == '__main__' :a = multiprocessing.Process(target=p)a.start()print('当前主进程id:',os.getpid(),'进程名字为:',multiprocessing.current_process())结果:
当前主进程id: 5508 进程名字为: <_MainProcess name='MainProcess' parent=None started>
发现结果中没有子进程了

带参数执行方法的时候也要注意书写规范,传递元组位数要和方法形参一一对应,字典也要用形参的名字,传参的时候允许元组和字典一起使用,但是字典中的参数相当于是元组中的一个补充

import multiprocessingdef p(name,age):print('我是',name)if __name__ == '__main__' :a = multiprocessing.Process(target=p,args=('Tom',),kwargs={"age":12})a.start()

下面说说线程,我们往往觉得线程和进程说的是一个东西,但其实他们不是一个东西,而之所以大家会觉得它们两个是一个东西,是因为一个程序的执行默认情况下由进程负责,CPU进行调度,默认情况下一个进程中只有一个线程,所有导致很多人认为它们是一个东西

不过值得高兴的时,线程的操作方式和进程没差别,只不过部分的名字不一样而已

import threadingdef p(name,age):print('我是',name,threading.current_thread())if __name__ == '__main__' :#启动两个线程并打印它的名称a = threading.Thread(target=p,kwargs={"name":"Tom","age":12})a.start()b = threading.Thread(target=p,kwargs={"name":"Tom","age":12})b.start()结果:
我是 Tom <Thread(Thread-1, started 14528)>
我是 Tom <Thread(Thread-2, started 14732)>

这里给大家贯彻几个概念,第一是不管是线程还是进程,他们的运行都是无序的,下面以线程为例写一个测速程序

import threading
import timedef p():time.sleep(0.2)print('我是',threading.current_thread())if __name__ == '__main__' :for i in range(10) :a = threading.Thread(target=p)a.start()结果:
我是 <Thread(Thread-10, started 8824)>
我是 <Thread(Thread-5, started 11848)>
我是 <Thread(Thread-6, started 3796)>
我是 <Thread(Thread-2, started 11240)>
我是 <Thread(Thread-3, started 7480)>
我是 <Thread(Thread-4, started 8912)>
我是 <Thread(Thread-1, started 7240)>
我是 <Thread(Thread-8, started 9240)>
我是 <Thread(Thread-9, started 11236)>
我是 <Thread(Thread-7, started 3612)>

第二个是,无论是线程还是进程,主的永远会等待子的结束任务,它才会结束

import threading
import timedef p():while True :print('-----')time.sleep(1)if __name__ == '__main__' :a = threading.Thread(target=p)a.start()print('over')结果:
-----
over
-----
-----
。。。。。。。。

第三点是,线程之间共享资源,但是进程不共享,如下例子可以说明这一点

import threading
import timeaa = []def p():for i in range(3) :time.sleep(1)aa.append(i)print('add:',i)def q():time.sleep(5)print(aa)if __name__ == '__main__' :a = threading.Thread(target=p)a.start()b = threading.Thread(target=q)b.start()结果:
add: 0
add: 1
add: 2
[0, 1, 2]

第四点,在线程共享资源的时候,有些时候,如果你直接共享,肯定会出现问题,比如下面这种情况

import threading
import timeaa = 0def p():for i in range(1000000000) :global aaaa += 1print(aa)def q():for i in range(100000000) :global aaaa += 1print(aa)if __name__ == '__main__' :a = threading.Thread(target=p)a.start()b = threading.Thread(target=q)b.start()结果:
122831590
1016427767

当然我上面这个例子是最简单的一个,总之直接共享,很大可能不是报错就是数据不对,那么这种情况下怎么办呢?请看下篇知识点

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

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

相关文章

详解 Spark SQL 核心编程知识

一、SparkSQL 概述 1. 概念 Spark SQL 是 Spark 用于结构化数据 (structured data) 处理的 Spark 模块&#xff0c;使用 SQL 的方式简化 RDD 的开发 2. Hive VS SparkSQL Hive 是早期唯一运行在 Hadoop 上的 SQL-on-Hadoop 工具&#xff0c;但是 MapReduce 计算过程中大量的中…

URL路由基础

本书1-7章样章及配套资源下载链接: https://pan.baidu.com/s/1OGmhHxEMf2ZdozkUnDkAkA?pwdnanc 源码、PPT课件、教学视频等&#xff0c;可以从前言给出的下载信息下载&#xff0c;大家可以评估一下。 对于高质量的Web应用来讲&#xff0c;使用简洁、优雅的URL设计模式非常…

时间序列的谱分解

refer&#xff1a;15.pdf (berkeley.edu) Stat 153 Fall 2010 (berkeley.edu)

linux mtd分区应用操作sample之某分区擦除

什么是擦除? 把flash相关的区域数据bit置为1的过程 #include <mtd/mtd-user.h> #include <mtd/mtd-abi.h> struct erase_info_user {__u32 start; // 起点 __u32 length; //长度 块大小对齐 不然报参数失败 };struct erase_info_user64 {__u64 sta…

Linux 驱动设备匹配过程

一、Linux 驱动-总线-设备模型 1、驱动分层 Linux内核需要兼容多个平台&#xff0c;不同平台的寄存器设计不同导致操作方法不同&#xff0c;故内核提出分层思想&#xff0c;抽象出与硬件无关的软件层作为核心层来管理下层驱动&#xff0c;各厂商根据自己的硬件编写驱动…

【逻辑回归】Logistic Regression逻辑回归模型学习笔记

文章目录 序言1. 线性回归2. 逻辑回归2.1 引入逻辑回归的原因2.2 逻辑回归2.3 逻辑回归的应用 3. 逻辑函数3.1 sigmoid函数3.2 sigmoid函数的性质3.3 决策边界3.4 对数几率 4. 损失函数4.1 为什么说逻辑回归时概率类模型4.2 为什么要进行极大似然估计4.3 利用MLE如何推导出损失…

Linux下的配置工具menuconfig+配置文件(Kconfig/.config/defconfig)

我们都知道,嵌入式开发中,或者说C语言中,配置基本都是通过宏定义来决定的,在MCU开发中,代码量比较小,配置项也比较少,我们直接修改对应的宏定义即可。 但是,Linux开发中,操作系统、驱动部分还有应用部分加起来,代码量极大,配置项目也非常多,这时候,就需要对这些配…

HackTheBox-Machines--Cronos

文章目录 0x01 信息收集0x02 命令注入漏洞0x03 权限提升 Cronos 测试过程 0x01 信息收集 1.端口扫描 发现 SSH&#xff08;22&#xff09;、DNS&#xff08;53&#xff09;、HTTP&#xff08;80&#xff09;端口 nmap -sC -sV 10.129.227.2112.53端口开启&#xff0c;进行DNS…

【LeetCode刷题】前缀和解决问题:742.寻找数组的中心下标、238.除自身以外数组的乘积

【LeetCode刷题】Day 15 题目1&#xff1a;742.寻找数组的中心下标思路分析&#xff1a;思路1&#xff1a;前缀和思想 题目2&#xff1a;238.除自身以外数组的乘积思路分析思路1&#xff1a;前缀和思想 题目1&#xff1a;742.寻找数组的中心下标 思路分析&#xff1a; 其实题干…

【软件开发规范篇】前言

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

Linux——多线程(三)

在上一篇博客中我们讲到了在加锁过程中&#xff0c;线程竞争锁是自由竞争的&#xff0c;竞争能力强的线程会导致其他线程抢不到锁&#xff0c;访问不了临界资源导致其他线程一直阻塞&#xff0c;造成其它线程的饥饿问题&#xff0c;想要解决此问题又涉及一个新概念线程同步 一…

18 EEPROM读写

EEPROM 简介 EEPROM (Electrically Erasable Progammable Read Only Memory&#xff0c;E2PROM)即电可擦除可编程只读存储器&#xff0c;是一种常用的非易失性存储器&#xff08;掉电数据不丢失&#xff09;&#xff0c;EEPROM 有多种类型的产品&#xff0c;此次实验使用的是A…

32位与64位程序下函数调用的异同——计科学习中缺失的内容

前言 今天&#xff0c;通过一个有趣的案例&#xff0c;从反编译的角度看一下C语言中函数参数是如何传递的。 创建main.c文件&#xff0c;将下面实验代码拷贝到main.c文件中。 # main.c #include <stdio.h>int test(int a, int b, int c, int d, int e, int f, int g, …

Docker最新超详细版教程通俗易懂

文章目录 一、Docker 概述1. Docker 为什么出现2. Docker 的历史3. Docker 能做什么 二、Docker 安装1. Docker 的基本组成2. 安装 Docker3. 阿里云镜像加速4. 回顾 hello-world 流程5. 底层原理 三、Docker 的常用命令1. 帮助命令2. 镜像命令dokcer imagesdocker searchdocker…

解锁数据宝藏:高效查找算法揭秘

代码下载链接&#xff1a;https://gitee.com/flying-wolf-loves-learning/data-structure.git 目录 一、查找的原理 1.1 查找概念 1.2 查找方法 1.3平均查找长度 1.4顺序表的查找 1.5 顺序表的查找算法及分析 1.6 折半查找算法及分析 1.7 分块查找算法及分析 1.8 总结…

pytorch学习笔记5

transform 本质上作用是将图片通过transform这个这个工具箱获取想要的结果 tensor就是一个包含神经网络需要的一些理论基础的参数 from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from PIL import Image #tensor数据类型 #通过tra…

1985-2020 年阿拉斯加和育空地区按植物功能类型划分的模型表层覆盖率

ABoVE: Modeled Top Cover by Plant Functional Type over Alaska and Yukon, 1985-2020 1985-2020 年阿拉斯加和育空地区按植物功能类型划分的模型表层覆盖率 简介 文件修订日期&#xff1a;2022-05-31 数据集版本: 1.1 本数据集包含阿拉斯加和育空地区北极和北方地区按…

DPDK基础组件二(igb_uio、kni、rcu)

The Linux driver implementer’s API guide — The Linux Kernel documentation 一、igb_uid驱动 参考博客:https://zhuanlan.zhihu.com/p/543217445 UIO(Userspace I/O)是运行在用户空间的I/O技术 代码位置:dpdk----/kernel/linux/igb_uio目录 igb_uio 是 dpdk 内部实…

学习数据分析思维的共鸣

在这篇文章中&#xff0c;我将分享自己在成长过程中对数据分析思维的领悟&#xff0c;从《数据分析思维-产品经理的成长笔记》这本书引发的共鸣&#xff0c;到数据分析在不同岗位的广泛应用&#xff0c;再到如何将学习与快乐联系起来&#xff0c;以及沟通在数据分析中的重要性。…

cocos入门4:项目目录结构

Cocos Creator 项目结构教程 Cocos Creator 是一个功能强大的游戏开发工具&#xff0c;它为开发者提供了直观易用的界面和强大的功能来快速创建游戏。在使用 Cocos Creator 开发游戏时&#xff0c;合理地组织项目结构对于项目的可维护性和扩展性至关重要。以下是一个关于如何设…