Python渗透测试编程基础——线程、进程与协程

news2024/11/27 21:05:42

目录

 一、进程与线程的概念

1.进程

2.线程

3.进程和线程的关系

4.任务执行方式

二、Python中的Threading模块

1.线程模块介绍

2.Threading介绍

(1)方法和属性

(2)类方法

三、线程简单编写

1.流程

2.创建线程

(1)方法一

(2)方法二

3.例子

四、守护线程

五、线程同步技术

1.线程锁

(1)互斥锁Lock

(2)可重入锁RLock

(3)信号锁Semaphore

(4)事件锁Event

(5)条件锁Condition

(6)Barrier“阻碍”类

(7)queue.Queue()对象

(8)定时器Timer

2.with语句使用线程锁

六、多进程编程

1.全局解释器锁(GIL)

2.全局解释器锁(GIL)导致的问题

3.进程同步

4.进程间通信

七、并发编程方法比较

1.协程

2.多进程

3.多线程

4.多协程


 一、进程与线程的概念

1.进程

进程是系统中正在运行的一个应用程序;程序一旦运行就是进程。进程是资源分配的最小单位。(动态)

2.线程

它被包含在进程之中,是操作系统能够进行运算调度的最小单位。一个进程中可以并发多个线程,每条线程并行执行不同的任务,从而提高程序执行效率。

3.进程和线程的关系

一个进程可以有多个线程,但至少有一个线程; 一个线程只能属于一个进程。

线程是最小的执行单元; 进程是最小的资源管理单元。

4.任务执行方式

并行:同时运行,只有具备多cpu才能实现并行。

并发:是指资源有限的情况下,两者交替轮流使用资源,是伪并行,即看起来是同时运行。

多线程在单核cpu中并发执行,根据时间片切换线程。多线程在多核cpu中并行执行。

 

如:有n个任务(做饭、洗衣、整理衣物、拖地...)需要完成。 

二、Python中的Threading模块

1.线程模块介绍

python3进程多线程编程的模块有_thread和threading:

①_thread 模块:只提供基本的线程和锁定支持,不能很好的控制线程的运行。(不建议使用)

②threading 模块:提供了更高级别、功能更全面的线程管理。threading是常用的模块。

2.Threading介绍

(1)方法和属性

current_thread()

返回当前进程

active_count()

返回当前活跃的线程数

get_ident()

返回当前线程的线程标识符

enumerater()

返图当前活动Thed对象列表

main_thread()

返回主Tred对象

stack_size(size) | 返回线程栈大小;或为后续创建的线程设定栈大小为size

返回线程栈大小;或为后续创建的线程设定

TIMEOUT_MAX

Lock.acquire(), RLock.acquire(), Condition.wait()允许的最大超时时间 |

(2)类方法

Timer

用于在指定时间之后调用一个函数的情况

Event

事件类,用于线程同步

Condition

条件类,用于线程同步

Lock、RLock

锁类,用于线程同步

Semaphore

信号量类,用于线程同步

Barrier

阻碍”类,用于线程同步

三、线程简单编写

1.流程

创建线程,启动线程,等待线程结束

t = threading.Thread(target=xxx,args=(,)) #创建
t.start() #启动
t.join #等待结束

2.创建线程

(1)方法一

直接实例化对象threading.Thread对象

t = threading.Thread(target=xxx,args=(,)) #创建
t.start() #启动
t.join #等待结束

(2)方法二

创建线程子类来实例化线程对象(必须重写run方法)

class MyThread(threading.Thread):
    def _init_(self,arg):
        threading.Thread._init_()
        self.arg = arg
    def run(self):
        pass

如果不使用join()方法,主线程不会等待子线程执行完毕,而是继续往下执行它自己的代码。Python默认会等待最后一个线程执行完毕后才会退出

3.例子

用线程编写一个获取系统实时时间的程序

import threading
import time

def show_time():
    while True:
         print(f"\r{time.strftime('%Y-%m-%d %H:%M:%S')}",end='')
         time.sleep(1)

def main()
    t = threading.Thread(target=show_time())
    t.start()
    t.join

if _name_ == '_main_':
     main()

四、守护线程

在脚本运行过程中有一个主线程,若在主线程中创建了子线程,子线程的结束方式:

主线程会等待子线程完成后再退出。(非守护线程)

主线程运行结束时子线程将随主线程一起结束,而不论是否运行完成。(守护线程)

方法一:t = thredding.Thread(target=xxx,args=(,)),deamon = True)
方法二:t.deamon = True
方法三:t.setDaemon(True)

设置守护线程必须在启动线程前完成

五、线程同步技术

1.线程锁

当多个线程对一个共享的变量进行读写操作时,为了保证运行结果的正确性,通常需要对线程之间进行同步。当然,同步会降低并发的程度。threading模块中定义了几种线程锁类,以实现线程同步:

类名

描述

Lock

互斥锁

RLock

可重入锁

Semaphore

信号锁

Event

事件锁

Condition

条件锁

Barrier

栅栏,也叫阻碍类

(1)互斥锁Lock

Lock互斥锁:为原始锁,在锁定时不属于任何一个线程。是一种独占锁,同一时刻只有一个线程可以访问共享的数据。

使用方法:

初始化锁对象(创建锁对象)

将锁当做参数传递给任务函数

在任务中加锁(acquire)

使用后释放锁(release)

(2)可重入锁RLock

可重入锁RLock:

在同一个线程中,RLock.acquire()可以被多次调用,最后也必须由获取它的线程来释放它。

acquire()和release() 对可以嵌套。利用该特性,可以解决部分死锁问题。

Lock与RLock的对比:

锁名

是否同一线程加锁或释放锁

是否可重复加锁

Lock

RLock

(3)信号锁Semaphore

信号锁Semaphore:

类名:BoundedSemaphore。

这种锁允许一定数量的线程同时更改数据,它不是互斥锁。比如地铁安检,排队人很多,工作人员只允许一定数量的人进入安检区,其它的人继续排队。

(4)事件锁Event

运行机制:

定义一个全局Flag,如果Flag为False,执行wait()方法时就会阻塞,如果Flag为True,线程不再阻塞。这种锁,类似交通红绿灯(默认是红灯),它属于在红灯的时候一次性阻挡所有线程,在绿灯的时候,一次性放行所有排队中的线程。

事件锁提供的方法:

方法名

说明

set()

将Event对象内部的

信号标志设置

为真

clear()

将Event对象内部的

信号标志设置为假

is_set()

判断其内部信号标志的状态

wait()

信号为假时阻塞线程,信号为真时或超时再唤醒

(5)条件锁Condition

条件锁的作用:

使用Condition对象可以在某些事件触发后才处理数据或执行特定的功能代码,可以用于不同线程之间的通信或通知,以实现更高级别的同步。

条件锁提供的方法:

方法名

说明

** **

acquire()

加锁

release()

解锁

wait([timeout])

调用wait()会释放****锁

被唤醒之后又重新获得锁

,然后继续执行。

使用前,线程必须已获得锁

notify()

从等待池挑选一个线程并通知,收到通知的线程将自动调用acquire()尝试获得锁定,其他线程仍然在等待池中。

调用该方法

不会释放锁

notifyAll()

通知等待池中所有线程,这些线程都将进入锁定池尝试获得锁定。

(6)Barrier“阻碍”类

Barrier的作用:

多个线程运行到某个点以后每个线程都需要等着其他线程准备好以后再同时进行下一步工作,此时就可以用Barrier对象。

①主线程中创建阻碍锁

lock=threading.Barrier(parties,action=None,timeout=None)
parties:设置等待的线程数
action:如果设置,则表示当等待的线程达到了指定数量,在释放它们之前,将由其中一个线程调用action指定的操作。
timeout:设置所有线程默认的等待时间。

②子线程中用wait()等待被唤醒

lock.wait( timeout=None)
imeout——设置线程的等待时间
如果等待超时,会引发BrokenBarrierError错误。
返回值:返回一个介于0\~parties-1之间的整数。

线程调用该方法后会阻塞,当指定数量线程都调用了该方法后,先由其中一个线程执行action指定的操作(如果有),再同时释放这些线程并继续执行后面的代码。

(7)queue.Queue()对象

队列 Queue的作用:

一种先入先出的结构。queue对象适合需要在多个线程之间进行信息交换,实现了多线程编程所需要的所有锁语义。

①创建queue对象

q = queue.Queue(maxsize=0)
maxsize:设置队列大小
如果maxsize<= 0,队列大小是无限的。

②队列对象常用方法

方法

说明

put(item,block=True,timeout=None)

在队列尾部追加元素     

get(block=True,timeout=None)

在队列头部取元素

Queue.qsize()

返回队列的大小

Queue.empty()

队列为空则返回True,否则返回False

Queue.full()

队列满则返回True,否则返回False

Queue.join()

队列为空时执行别的操作

(8)定时器Timer

定时器Timer类是threading模块中的一个小工具,用于指定n秒后执行某操作。

2.with语句使用线程锁

所有的线程锁都有一个加锁和释放锁的动作,非常类似文件的打开和关闭。通过with上下文管理器,可以确保锁被正常释放。其格式如下:

with some_ Lock:    
    #执行任务

六、多进程编程

1.全局解释器锁(GIL)

Python设计之初为了数据安全所做的决定。CPython中的某个线程想要执行,必须先拿到GIL,但在CPython进程中GIL只有一个。

2.全局解释器锁(GIL)导致的问题

无论CPU有多少核,由于只有一个GIL,导致同一时刻只能执行一个线程,此时多线程并不能大幅度的提供处理效率。Python中想要充分利用多核CPU,就用多进程。因为每个进程有各自独立的GIL。Python标准库multiprocessing支持使用类似于threading的用法来创建与管理进程。

建议:IO密集型任务中使用多线程,如socket,爬虫。计算密集型任务中使用多进程,如金融分析。

3.进程同步

与多线程一样,当多个进程对一个共享的变量进行读写操作时,为了保证结果的正确性,通常需要对进程之间进行同步。

4.进程间通信

进程间通常数据是独立的,不能共享数据。进程间通信据的方式:  共享内存、管道、信号、socket、外部存储等。

常用方式:

方式

类或函数

队列

multiprocessing.Queue()

管道

multiprocessing.Pipe()

七、并发编程方法比较

Python中执行并发任务有三种方式:

*   多进程

*   多线程

*   多协程

包含关系:一个进程中可启动多个线程,一个线程中可启动多个协程。

1.协程

协程:称为微线程,是比线程更轻量级。可在一个线程中启动多个协程进行函数执行切换来实现并发。

协程始终都能获得到GIL,所以不会受GIL影响。如果希望通过协程利用多核CPU的计算能力,那么可通过多进程与协程配合的模式来实现。

协程库:asyncio

2.多进程

优点:

*   可以利用多核CPU进行并行计算

*   子进程之间数据独立,安全性较好

缺点:

*   占用资源最多

*   进程间切换的开销也比较大

*   可以启动数目最少

使用场景:CPU密集型计算。

3.多线程

优点:

*   相比于进程更轻量级

*   占用资源更少

缺点:

*   受限于全局解释器锁GIL,在CPython中,多线程只能并发执行,无法充分利用多核处理器。

*   启动数目有限制,占用内存资源,有线程切换的开销。

适用场景:IO密集型计算

4.多协程

优点:

*   内存开销最小,可启动数目最多(可多达几万个)

缺点:

*   支持的库有限制(如requests库不支持,需用aiohttp); 代码实现复杂。

适用场景:IO密集型计算、需要启动超多任务、有现成的库支持。

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

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

相关文章

云原生技术在云计算中的应用探讨

第一章&#xff1a;云原生技术的概念与发展 云原生技术是一种针对云计算环境设计的应用程序开发和部署方法&#xff0c;主要目标是提高应用程序的可伸缩性、可移植性、高可用性和自动化管理等方面的特性。这种技术是近年来在云计算领域兴起的一个新的开发模式&#xff0c;它主要…

大模型“涌现”的思维链,究竟是一种什么能力?

听说最近AI大厂的开发人员和高校的NLP研究人员&#xff0c;都在琢磨&#xff0c;怎么让大模型“涌现”。那画面莫名就让我想到了程序员给服务器上香来保佑不宕机&#xff0c;都有种求诸于天的玄学。 所谓“涌现”,在大模型领域指的是当模型突破某个规模时&#xff0c;性能显著提…

商城管理系统的数据表从属关系+navicat建表操作+数据库文件转储并入代码操作

1&#xff0c;商城管理系统的数据表从属关系 在商城管理系统中&#xff0c;我们会面临属性分组的问题&#xff0c;商品表与分类表需要建立链接&#xff1b; 在控制类中我们将分类表中属性类传过来&#xff0c;与商品值params建立链接 public R list(RequestParam Map<Strin…

基于matlab使用波束成形对点对点 MIMO-OFDM 系统进行建模

一、前言 此示例展示了如何使用波束成形对点对点 MIMO-OFDM 系统进行建模。最近的无线标准&#xff08;如 802.11x 系列&#xff09;采用了多输入多输出 &#xff08;MIMO&#xff09; 和正交频分复用 &#xff08;OFDM&#xff09; 技术的组合&#xff0c;以提供更高的数据速率…

万字长文 - Nature 综述系列 - 给生物学家的机器学习指南 2 (传统机器学习方法如何选择)...

万字长文 - Nature 综述系列 - 给生物学家的机器学习指南 1 传统的机器学习 我们现在讨论几种关键的机器学习方法的优势和劣势。表1显示了不同机器学习方法的比较。我们首先讨论不基于神经网络的方法&#xff0c;有时被称为“传统机器学习”。 图3显示了一些传统的机器学习方法…

【算法基础】常见排序算法(持续更新中)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有…

【KVM虚拟化】· 图形化KVM安装linux

目录 &#x1f341;虚拟化技术 &#x1f342;KVM的整体结构 &#x1f342;KVM 的功能列表 &#x1f342;KVM 工具集合 &#x1f341;安装kvm虚拟化功能 &#x1f341;创建虚拟机 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;KVM虚拟化…

FreeRTOS 信号量(二) ------ 计数型信号量

文章目录 一、计数型信号量1. 计数型信号量简介2. 创建计数型信号量①函数 xSemaphoreCreateCounting()②函数 xSemaphoreCreateCountingStatic() 3. 计数型信号量创建过程分析4. 释放和获取计数信号量 二、计数型信号量操作实验 一、计数型信号量 1. 计数型信号量简介 有些资…

数据结构与算法(小议递归)

文章目录 前言一、递归是什么&#xff1f;二、在什么时候适用递归1.测试一下 总结 前言 递归是一种常用的算法设计&#xff0c;递归就是一种循环推理。简单来说就是调用原算法本身的算法。 这里主要探讨递归的使用&#xff0c; 一、递归是什么&#xff1f; 用一个简单的例子来…

嵌入式代码查看分析利器---Understand

平时在开发嵌入式程序的时候大多数使用的都是keil软件&#xff0c;一般小的工程使用keil没感觉到有什么问题&#xff0c;但是当工程比较大的时候&#xff0c;比如移植了FreeRTOS系统或者LWIP网络系统时&#xff0c;代码全部编译一次就要花费很长世间&#xff0c;特别是开启了点…

CIKM论文解读 | 淘宝内容化推荐场景下对多场景全域表征的思考与应用

我们结合逛逛推荐场景中的具体问题&#xff0c;从多场景全域表征的视角进行了一系列的探索与内容推荐场景的应用&#xff0c;从全域表征的范围、信息迁移方式以及模型框架的应用等维度展开我们的优化工作&#xff0c;取得了阶段性的优化经验和业务效果。 背景介绍 淘宝逛逛自20…

鸿蒙混合打包。在现有安卓应用的基础上扩展鸿蒙的特性,以最快的速度布局鸿蒙生态!

鸿蒙混合打包 介绍 鸿蒙混合打包。在现有安卓应用的基础上扩展鸿蒙的特性&#xff0c;以最快的速度布局鸿蒙生态&#xff01; 参考&#xff1a;京东APP鸿蒙版上架实践。本项目只是这篇文章的一个验证&#xff0c;让更多的兄弟们可以少走弯路。 我尽可能把每一步的改动作为一…

【HarmonyOS】【JS】Tabs如何设置区分TabBar和TabContent的分割线不显示

【关键字】 Tabs&#xff0c;分割线 【问题描述】 使用JS开发HarmonyOS应用时&#xff0c;使用Tabs组件&#xff0c;默认自带TabBar和TabContent的蓝色分割线&#xff0c;由于蓝色分割线样式不可设置&#xff0c;若不想要此蓝色分割线&#xff0c;如何去除蓝色分割线&#xf…

搭建外网minecraft服务器方案

很多minecraft服务器主都想自己搭建一个外网可以访问的minecraft服务器&#xff0c;在没有外网IP的情况下&#xff0c;一般都是使用Logmein Hamachi方案。这种方案有它的弊端&#xff0c;需要客户机安装Hamachi&#xff0c;十分不方便。另外&#xff0c;免费版只支持5人&#x…

C++三大特性—继承 “基类与派生类之间的类型转换与赋值转换”

理解基类与派生类之间的类型转换是理解C语言面向对象编程的关键所在 继承 通过继承联系在一起的类构成一种层次关系&#xff0c;层次关系的根部有一个基类&#xff0c;其他直接或间接从基类继承而来&#xff0c;称为派生类。    继承(inheritance)机制是面向对象程序设计使代…

Spring RabbitMQ 实现消息队列延迟

1.概述 要实现RabbitMQ的消息队列延迟功能&#xff0c;一般采用官方提供的 rabbitmq_delayed_message_exchange插件。但RabbitMQ版本必须是3.5.8以上才支持该插件&#xff0c;否则得用其死信队列功能。 2.安装RabbitMQ延迟插件 检查插件 使用rabbitmq-plugins list命令用于查看…

C++引用进阶篇:让你的程序更加高效、安全、简洁

文章目录 前言1. 引用和临时数据&#x1f351; 什么样的临时数据会放到寄存器中&#x1f351; 关于常量表达式&#x1f351; 引用也不能指代临时数据&#x1f351; 引用作为函数参数 2. 为const引用创建临时变量3. const引用与转换类型&#x1f351; 引用类型的函数形参请尽可能…

SPFA 算法:实现原理及其应用

文章目录 一、前言二、SPFA 算法1、SPFA算法的基本流程2、代码详解 三、SPFA 算法已死 &#xff1f; 一、前言 SPFA算法&#xff0c;全称为Shortest Path Faster Algorithm&#xff0c;是求解单源最短路径问题的一种常用算法&#xff0c;它可以处理有向图或者无向图&#xff0…

PySide2 QWebEngine与Web js交互

文章目录 单向交互双向传值案例 单向交互 QWebEngineView加载web页面&#xff0c;web页面中点击按钮&#xff0c;执行js代码&#xff0c;js的返回值传给QWebEnginePage&#xff0c;使用python进行保存结果。 单向&#xff0c;js向python(PySide2)端传输数据。 前端实现 <…

前端web3入门脚本三:一键完成与dex的交互,羊毛党必备

前言 该脚本用途&#xff1a;一键可以完成与dex的所有交互&#xff0c;包括2次swap&#xff0c;添加/移除流动性&#xff0c;以及farm和提取LP。一次运行可以有6条交易记录。 无论是个人单刷还是羊毛党批量地址刷交互都完美适配。当然反女巫方案不在这次文章的讨论范围内。 一、…