并发编程【2】

01.什么是僵尸进程,孤儿进程

       僵尸进程是指在进程已经终止但是其父进程尚未终止信息(退出状态码)的情况下。保留在进程表中的进程。僵尸进程不占用实际的系统资源,但会占用一个进程ID,并且会在系统中产生垃圾。

        孤儿是指在网络中失去父进程(创建它的进程)却继续运行的子进程。通常是由于父进程异常退出或未正确管理子进程而导致。它就会并由init进程来处理孤儿进程的退出状态。在从进程表中删除孤儿进程的记录。

02.什么是互斥锁,优点缺点

        什么是互斥锁:是一种用于多线程编程中的同步机制,用于保护共享资源,确保在同一时间只有一个线程可以访问该资源。

优点:

  1. 确保数据完整性:

  2. 简单易用:使用互斥锁可以方便地实现对共享资源的互斥访问,提供了一种简单可靠的同步方法。

  3. 高效性能:

缺点:

  1. 死锁风险:如果在设计和使用互斥锁时不小心,可能会导致死锁问题,即多个线程相互等待对方释放锁而无法继续执行。

  2. 性能开销:在互斥锁的保护下,只有一个线程能够访问共享资源,其他线程需要等待,这可能引入一定的性能开销。

  3. 可能存在优先级反转:当高优先级的线程获取到互斥锁时,可能会阻塞低优先级的线程,导致优先级反转问题。

03.什么是守护进程,如何实现

        守护进程(Daemon)是在操作系统中以后台形式运行的一类特殊进程。它通常在系统启动时启动,并且在整个系统运行期间持续运行,独立于终端会话。

安包daemon

python daemon.py

04.僵尸和孤儿哪个危害大,为什么

        僵尸进程会占用大部分的资源,并且这部分资源没人来处理

        孤儿进程虽然父进程没了,但是 init 进程会将这部分资源释放掉

程序:一堆数据和代码

进程:跑起来的程序

线程:在进程内开始的进程

【一】进程

【1】什么是进程

        进程就是计算机中正在运行的程序的实例。它是操作系统进行任务调度和资源分配的基本单位。每个进程拥有自己独立的内存空间,包括代码、数据和堆栈等信息。

而复杂执行任务则是CPU

【2】进程的特点

  • 独立性:每个进程都是独立运行的实体,相互之间不会干扰或者影响。它们有各自的内存空间。

  • 并发性:多个进程可以同时运行在多个核处理器上,实现并行计算和提高系统的吞吐量。

  • 随机性:操作系统决定进程的调度顺序,根据调度策略分配CPU时间片给不同的进程,使得它们交替执行,给用户带来了随机性的体验。

  • 可抢占性:操作系统可以暂停一个进程的执行,并将CPU资源分配给其他进程。当资源可用时,被暂停的进程可以继续执行。

  • 共享性:进程之间可以共享资源,比如打开的文件、网络连接等。但是需要通过同步机制来确保数据的一致性和安全性。

        进程是多任务系统的基础,它使得计算机能够同时运行多个程序,并实现并发执行。操作系统通过进程管理群来隔离和调度进程,分配计算机资源,确保系统的稳定性和效率。

【3】进程与程序的区别

  • 程序仅仅只是一堆代码而已

  • 而进程指的是程序的运行过程。

【4】单进程

        单进程指在操作系统中只有一个进程在运行。这意味着系统一次只能执行一个任务或程序,没有并发的能力。当一个任务或程序执行时,其他任务或程序需要等待。

适用场景:

        单进程适用于一些简单的应用场景,如一些小型的工具或者脚本,不需要同时处理多个任务的情况。

【5】多进程

        多进程指早操作系统中同时运行多个独立的进程。每个进程拥有自己独立的资源和执行环境,可以并发地执行。多进程可以利用多核处理器的性能,提高系统的吞吐量和响应速度。

多进程的适用场景:

        适合用于需要同时处理多个任务或者程序的复杂应用场景,如并行计算、服务器处理、大规模数据处理等:

比较单进程和多进程的优缺点:

  • 单进程相对简单,适用于小规模、简单的应用场景、开销较小。

  • 多进程能够提高系统的并发处理能力,可以重充分利用核处理器的性能,但也会增加系统的开销和复杂性。

  • 单进程无法同时处理多个任务,可能会导致整个系统的响应速度变慢。

  • 多进程能够同时处理多个任务,并发执行,提高四天的性能和效率,但需要考虑进程通信和资源管理等问题。

【二】线程

【1】什么是线程

        线程是计算机科学中的一个重要概念,指的是在一个进程内执行的独立任务。线程是操作系统能够进行运算调度的最小单位。在现代操作系统中,每个进程可以拥有多个线程,这些现场共享进程的资源,同时有具有独立的执行流程。

【2】线程的特点

  • 轻量级:线程比进程消耗更少的资源,可以创建大量的线程而不会对系统造成重大的影响。

  • 共享内存:线程之间可以共享进程的内存空间,这使得线程之间的通信更加方便快捷。

  • 可以并发执行:多个线程可以同时执行,从而提高程序的运行效率。

  • 非独立调度和分配CPU时间:线程不能脱离进程单独运行,操作系统会将CPU时间分配给进程中的所有线程。

  • 状态切换开销小:相对进程而言,线程的状态切换开销较小,因为线程间共享了进程的资源,状态切换是只需要保存和恢复少量的上下文信息。

  • 安全性问题:由于线程共享的内存空间,因此需要采用同步机制来确保线程之间的数据访问安全。

【2】单线程

        单线程指的是程序只有一个主线程在执行。在单线程模型中,所有的任务按照顺序依次执行,每个任务必须等待前面的任务完成后才能执行。

适用场景:

一些简单的程序或者任务间没有明显的并发需求的场景。

【3】多线程

        进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是CPU上的执行单位。

【4】什么是多线程

        多线程是指早单个进程中同时运行多个线程的技术。线程是操作系统进行任务调度和资源分配的基本单位,它比进程更轻量级,可以共享进程的资源,如内存卡就、文件句柄等。多线程技术可以提高程序的并发性和响应能力,实现更高效的计算和资源利用。

【5】与单线程相比,多线程具有一下优缺点:

  • 更高的并发性:多个线程可以并行执行,从而提高程序的处理能力和响应速度。

  • 更高的资源利用率:多个线程可以共享进程的资源,避免了资源的重复占用和浪费。

  • 更灵活的编程模型:多线程使得程序具有更零下的结构和设计,可以更好地适应不同的需求。

缺点

  • 难以排查和调试问题

  • 数据同步和共享问题

  • 资源消耗

  • 程序设计复杂性增加

  • 并发控制和竞争条件

首先分析页面 ----> 就是要页面上的图片

页面上的图片----> 图片上的数据

图片上的数据 ----> 二进制数据

二进制数据 ----> 数据写入

【三】进程间通信

【1】什么是进程间通信

  • 进程间通信 是指两个或多个进程之间进行信息交换的过程。

  • 它是一种计算机编程技术,用于在不同进程之间共享数据和资源。

        是指在多进程系统中,不同进程之间进行数据交换和共享的一种机制。

【2】如何实现进程通信

  • 借助与消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出。

  • 这种通信方式是非阻塞的,即发送进程不需要等待接收的响应即可继续执行。

  • multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的

【3】什么是管道

        管道是一种半双工的通信方式,他可以在具有亲缘关系的父子进程或者兄弟进程之间通信。在Unix/Linux系统中, 可以使用pipe()函数创建管道,通过fork()系统调用创建子进程后,父子进程就可通过管道通信。

  • stdin、stdout和stderr是Python中三个内置文件对象,它们分别代表标志输入、标准输出和标准错。这些也可以作为管道使用。

  • 当我们在一个进程中使用read方法读取管道内的消息后买它进程将无法在获取该管道内的任何其他消息。

  • 因此,我们需要使用锁或者其他同步机制来确保能够正确地访问和修改共享资源。

【4】什么是队列(管道 + 锁)

        队列是一种常见的数据结构,用于在多线程或者多进程环境中实现线程见的安全通信和数据交换。队列可以看作是一个先进先出(FIFO) 的缓冲区,其中的袁术按照添加的顺序进行处理。

队列:先进先出

堆栈: 后进先出

        锁:是一种同步机制,用于确保在同一时刻只有一个线程可以访问被锁定的资源。在队列中,锁用于保护对共享数据的访问,防止多个现场同时修改数据造成的冲突和不一致。

        队列是一种线程安全的数据结构,它支持在多线程环境中高效地实现生产者-消费者模型。

【5】进程间通信的目的

  • 存是为了更好的取

  • 千方百计的存

  • 简单快捷的取

【四】队列的使用

        队列是一种常见的数据结构,用于实现先进先出的缓冲区。

queue模块: 可以使用queue.Queue类来创建一个队列对象,然后使用器提高的方法来进行元素的入列和出对操作。

  • put(item) :将元素 item 入队。

  • get() :从队列中出队返回一个元素。

  • empty() :判断队列是否为空。

  • full() :判断队列是否已满。

  • qsize() :获取队列中当前元素的个数。

  • q.get_nowait() : 队列无数据报错。

    q = queue.Queue()
    q.put(1)
    q.put(21,)
    ​
    print(q.get())
    print(q.get())
    print(q.empty())
    print(q.full())
    # 1
    # 21
    # True
    # False
    # popleft()方法从队列的头部弹出一个元素。
    from collections import deque

    deque是Python标准库 collections 模块中的双端队列实现。deque提高了与列表类似的操作,但在头部和尾部都能高效地进行插入和删除操作。可以在append()添加在队列尾部

    popleft()方法从队列的头部弹出一个元素。 ​

# popleft()方法从队列的头部弹出一个元素。q = deque()
q.append(123)
q.append(456)
print(q.popleft())
print(len(q))
# 123
# 1

        第三方库 queue:除了标准库中的 queue 模块,还有一些第三方库也提供了更高级和更强大的队列实现。例如,queue 库是一个线程安全的队列实现,提供了更多的功能和选项,如优先级队列、固定大小队列等。

from queue import PriorityQueue
​
q = PriorityQueue()
q.put((2, 'Item 2'))
q.put((1, 'Item 1'))
print(q.get())  # 输出: (1, 'Item 1')
from multiprocessing import Process,Queue
# Queue队列的使用方法
def producer(q):for i in range(5):q.put(i)print(f'生产者:{i} 这是 生产者!')
​
​
def consumer(q):while True:item = q.get()if item is None:breakprint(f'消费者: {item} 这是消费者')
​
if __name__ == '__main__':q = Queue()p1 = Process(target=producer, args=(q,))p2 = Process(target=consumer, args=(q,))p1.start()p2.start()p1.join() # 这就是解决消费者大于生产者的问题p2.join()# 生产者:0# 这是# 生产者!# 生产者:1# 这是# 生产者!# 生产者:2# 这是# 生产者!# 生产者:3# 这是# 生产者!# 消费者: 0# 这是消费者# 生产者:4# 这是# 生产者!# 消费者: 1# 这是消费者# 消费者: 2# 这是消费者# 消费者: 3# 这是消费者# 消费者: 4# 这是消费者

【五】进程通信(IPC机制)

【1】什么是IPC机制

  • IPC机制指进程间通信机制,进程间通信,进程与进程之间数据交互

【2】子进程与主进程之间通过队列进行通信

from multiprocessing import Process, Pipe
​
# 创建一个子进程函数
def child_process(conn):# 向管道写入消息conn.send('这是子进程发出的消息')print('子进程向管道写入了一条消息')
​
if __name__ == '__main__':# 【一】创建管道对象:注意这里是使用的 multiprocessing 里面的 Pipeparent_conn, child_conn = Pipe()# 【二】创建子进程:目标函数和参数带进去child_proc = Process(target=child_process, args=(child_conn,))# 【三】启动子进程child_proc.start()# 【四】主进程读取消息msg_from_child = parent_conn.recv()# 【五】查看消息print(msg_from_child)# 子进程向管道写入了一条消息# 这是子进程发出的消息

【六】生产者和消费者模型

生产者和消费者模型是一种常用的并发编程模型,它主要用于解决生产者和消费者之间的数据交互问题。

【1】生产者

生产者负责生成数据,并将数据放入共享的缓冲区。

【2】消费者

消费者则从缓冲区中获取数据进行处理。

import threading
import queue
import time
​
# 共享的缓冲区
buffer = queue.Queue(5)
​
# 退出标志位,初始为 False
exit_flag = False
​
# 生产者函数
def producer():while not exit_flag:# 模拟生产数据data = f'数据'print(f'生产者生产了:{data}')# 将数据放入缓冲区buffer.put(data)time.sleep(1)
​
# 消费者函数
def consumer():while not exit_flag or not buffer.empty():# 从缓冲区获取数据data = buffer.get()print(f'消费者消费了:{data}')# 模拟处理数据time.sleep(2)buffer.task_done()
​
if __name__ == '__main__':# 创建生产者线程producer_thread = threading.Thread(target=producer)# 创建消费者线程consumer_thread = threading.Thread(target=consumer)
​# 启动线程producer_thread.start()consumer_thread.start()
​# 等待用户输入,回车键退出input("按回车键退出程序\n")
​# 设置退出标志位为 Trueexit_flag = True
​# 等待线程结束producer_thread.join()consumer_thread.join()

小结:

【一】生产者和消费者模型总结

        生产者 : 生产数据 生产完所有数据以后要加一个标志位

        消费者 : 消费数据 从生产者生产的数据中拿出所有数据

【二】解决生产者和消费者不平稳

        一 Queue 在生产者生产数据的结尾 ---> 放一个标志位 消费者消费数据 ---> 消费到最后一个数据的时候,得到标志位知道生产的数据空了 --> 结束了 【三】解决生产者和消费者不平稳二 JoinableQueue

        在生产者生产数据的结尾 ---> 放一个标志位 join() 在消费者消费数据的 ----> 正产消费 ---> 在消费数据的结尾 task_done() ---> 自动检索上面生产者是否存在 join

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

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

相关文章

蒙特卡洛模拟之合成控制法

蒙特卡洛模拟之合成控制法(Monte Carlo Simulation in Synthetic Control Method)是一种用于评估政策效果的统计方法。该方法通过对比实验组和合成控制组之间的差异,从而估计政策的影响。 合成控制法是一种非实验性的政策评估方法&#xff0…

01.领域驱动设计:微服务设计为什么要选择DDD学习总结

目录 1、前言 2、软件架构模式的演进 3、微服务设计和拆分的困境 4、为什么 DDD适合微服务 5、DDD与微服务的关系 6、总结 1、前言 我们知道,微服务设计过程中往往会面临边界如何划定的问题,不同的人会根据自己对微服务的理 解而拆分出不同的微服…

mysql-线上常用运维sql

1.表备份 INSERT INTO table1 SELECT * FROM table2; 2.用一个表中的字段更新另一张表中的字段 UPDATE table2 JOIN table1 ON table2.id table1.id SET table2.column2 table1.column1; 3.在MySQL中,查询一个表的列字段值是否包含另一个表的字段,…

vue2 事件总线

原图下载:https://download.csdn.net/download/weixin_47401101/88788636

面向Java开发者的ChatGPT提示词工程(11)扩写

什么是扩写? 扩写是指将较短的文本交给GPT生成更长的文本。比如:根据一组基本指令,写出一封完整的电子邮件;或者根据一系列主题,创作出一篇包含这些主题的文章。 这样的技术,有着广阔的应用场景&#xff…

【蒸馏】目标检测蒸馏的不完全整理和个人笔记

其实仔细想想模型蒸馏的监督信号无非来自原先损失函数(分类,bbox)或者是相关组件(backbone,FPN),在这里我不太想用传统的logit蒸馏和feature map蒸馏来表示上面两种蒸馏方式, 主要是…

深入浅出 diffusion(4):pytorch 实现简单 diffusion

1. 训练和采样流程 2. 无条件实现 import torch, time, os import numpy as np import torch.nn as nn import torch.optim as optim from torchvision.datasets import MNIST from torchvision import transforms from torch.utils.data import DataLoader from torchvision.…

LayoutInflater.inflate全面解读

方法解析 LayoutInflater.inflate() 是 Android 系统中用于将 XML 布局文件转换成相应的 View 的方法。在 Android 开发中,我们经常使用此方法来动态创建和填充布局。 public View inflate(LayoutRes int resource, Nullable ViewGroup root, boolean attachToRoo…

LVGL v9学习笔记 | 12 - 弧形控件的使用方法(arc)

一、arc控件 arc控件的API在lvgl/src/widgets/arc/lv_arc.h 中声明,以lv_arc_xxx命名。 arc控件由背景圆弧和前景圆弧组成,前景圆弧的末端有一个旋钮,前景圆弧可以被触摸调节。 1. 创建arc对象 /*** Create an arc object* @param parent pointer to an object, it w…

Pyecharts 风采:从基础到高级,打造炫酷象形柱状图的完整指南【第40篇—python:象形柱状图】

文章目录 引言安装PyechartsPyecharts象形柱状图参数详解1. Bar 类的基本参数2. 自定义图表样式3. 添加标签和提示框 代码实战:绘制多种炫酷象形柱状图进阶技巧:动态数据更新与交互性1. 动态数据更新2. 交互性设计 拓展应用:结合其他图表类型…

深度学习-使用Labelimg数据标注

数据标注是计算机视觉和机器学习项目中至关重要的一步,而使用工具进行标注是提高效率的关键。本文介绍了LabelImg,一款常用的开源图像标注工具。用户可以在图像中方便而准确地标注目标区域,为训练机器学习模型提供高质量的标注数据。LabelImg…

Unity中URP下逐顶点光照

文章目录 前言一、之前额外灯逐像素光照的数据准备好后,还有最后的处理二、额外灯的逐顶点光照1、逐顶点额外灯的光照颜色2、inputData.vertexLighting3、surfaceData.albedo 前言 在上篇文章中,我们分析了Unity中URP下额外灯,逐像素光照中聚…

vue3 codemirror关于 sql 和 json格式化的使用以及深入了解codemirror 使用json格式化提示错误的关键代码

文章目录 需求说明0、安装1. 导入js脚本2.配置3.html处使用4.js处理数据(1)json格式化处理(2)sql格式化处理 5. 解决问题1:json格式化错误提示报错(1)打开官网(2)打开官网&#xff0…

qt学习:http+访问百度智能云api实现人脸识别

目录 登录到百度智能云,找到人脸识别 完成操作指引 开通 添加人脸库 查看人脸搜索与库管理的api文档 ​编辑 查看自己应用的api key 查看回应的数据格式 编程实战 配置ui界面 添加模块,头文件和定义变量

C#中类型装换

在C#中,可以使用Convert.ChangeType()方法进行类型转换。这个方法可以将一个对象转换为指定的类型。 以下是使用Convert.ChangeType()方法的示例: using System;public class MyClass {public int MyProperty { get; set; } }public class Program {pu…

【机器学习笔记】1 线性回归

回归的概念 二分类问题可以用1和0来表示 线性回归(Linear Regression)的概念 是一种通过属性的线性组合来进行预测的线性模型,其目的是找到一条直线或者一个平面或者更高维的超平面,使得预测值与真实值之间的误差最小化&#x…

ppt背景图片怎么设置?让你的演示更加出彩!

PowerPoint是一款广泛应用于演示文稿制作的软件,而背景图片是演示文稿中不可或缺的一部分。一个好的背景图片能够提升演示文稿的整体效果,使观众更加关注你的演示内容。可是ppt背景图片怎么设置呢?本文将介绍ppt背景图片设置的三个方法&#…

数据库 sql select *from account where name=‘张三‘ 执行过程

select *from account where name张三分析上面语句的执行过程 用到了索引 由于是根据 1.name字段进行查询,所以先根据name张三’到name字段的二级索引中进行匹配查 找。但是在二级索引中只能查找到 Arm 对应的主键值 10。 2.由于查询返回的数据是*&#xff0c…

5.Hive表修改Location,一次讲明白

Hive表修改Loction 一、Hive中修改Location语句二、方案1 删表重建1. 创建表,写错误的Location2. 查看Location3. 删表4. 创建表,写正确的Location5. 查看Location 三、方案2 直接修改Location并恢复数据1.建表,指定错误的Location&#xff0…

pytorch 卷积神经网络CNN

www.ai-xlab.com AI MOOC 卷积神经网络CNN 1 www.ai-xlab.com AI MOOC 卷积神经网络是近年发展起来,并广泛应用于图像处理,NLP等领域的一 种多层神经网络。 传统BP处理图像时的问题: 1.权值太多,计算量太大 2.权值太多&a…