python基础(六)

server/2024/12/4 17:47:57/

进程和线程

进程

进程就是操作系统中执行的一个程序,操作系统以进程为单位分配存储空间,每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程执行的辅助数据,操作系统管理所有进程的执行,为它们合理的分配资源。创新的进程有自己独立的内存空间,因此必须通过进程间通信机制(IPC,Inter-Process Communication)来实现数据共享,具体的方式包括管道、信号、套接字、共享内存区等。

验证进程独立空间

import multiprocessing
import os
#验证父进程在创建子进程时复制了进程及其数据结构每个进程都有自己独立的内存空间 
def process_func(value):# 在这个函数内部,尝试修改全局变量,但是这是在不同的内存空间中global_var = valueglobal_var += 1print(f"son PID {multiprocessing.current_process().pid}: global_var = {global_var}")if __name__ == "__main__":# 主进程中的全局变量global_var = 0# 创建并启动一个子进程p = multiprocessing.Process(target=process_func, args=(global_var,))p.start()p.join()    # 等待子进程完成# 主进程中打印全局变量的值print(f"Main process PID: {os.getpid()}, global_var = {global_var}")
#son PID 22916: global_var = 1
#Main process PID: 70036, global_var = 0

进程通信

import multiprocessing
import os
def sub_task(queue):print('子进程进程号:', os.getpid())  #子进程进程号: 3xxxfor i in range(1,5):queue.put(i)  #将元素放在队列的末尾‌if __name__ == '__main__':print('主进程号:', os.getpid())  #主进程号: xxxqueue = multiprocessing.Queue()p = multiprocessing.Process(target=sub_task, args=(queue,))p.start()counter = 0for i in 'ABCD':queue.put(i)p.join() #子任务已经完成for _ in range(8):print(queue.get(), end='')  #ABCD1234

线程

一个进程还可以拥有多个并发的线程,简单的说就是拥有多个可以获得CPU调度的执行单元,这就是所谓的线程。由于线程在同一个进程下,它们可以共享相同的上下文,因此相对于进程而言,线程间的信息共享和通信更加容易。当然在单核CPU系统中,真正的并发是不可能的,因为在某个时刻能够获得CPU的只有唯一的一个线程,多个线程共享了CPU的执行时间。

线程数据共享

import threading
from threading import Thread# 全局变量 主线程中创建了一个全局变量,那么这个变量对于所有的其他线程来说也是可见的
g_num = 0
lock = threading.Lock() #使用了一个锁lock来确保每次只有一个线程可以修改 g_num
def thread_function():global g_num   #每个线程都能看到 g_num 的变化with lock:     #with 语句保证在执行增加操作的时候lock会被自动获取和在操作完成后自动释放g_num += 1print(f"Thread {threading.get_ident()}: g_num = {g_num}")def main():t = Thread(target=thread_function)t.start()t1 = Thread(target=thread_function)t1.start()t.join()t1.join()
if __name__ == "__main__":main()

对比

import threading
from multiprocessing import Process
import time
lock=threading.Lock()
global_v=0
def show_fuc_without_lock():global global_vglobal_v+=1print(global_v)
def show_fuc_with_lock():global global_vglobal_v+=1print(global_v)
def show_fuc(name):for i in range(6):print(name,end=' ')time.sleep(1)print(i)def print_fuc(name):for i in 'abcde':print(name,end=' ')time.sleep(1)print(i)if __name__=='__main__':th1=threading.Thread(target=show_fuc, args=('show_fuc',))th2=threading.Thread(target=print_fuc,args=('print_fuc',))th1.start()  #多个线程完成多个任务th2.start()  #多个线程完成多个任务th1.join()th2.join()# p1=Process(target=show, args=('p_show',))# p2=Process(target=show1, args=('p_show1',))# p1.start()   #多进程的并行执行# p2.start() # threads = [threading.Thread(target=show_fuc_lock) for _ in range(10)]# for t in threads:#     t.start()# 等待所有线程完成 # for t in threads:#     t.join()

pickling和unpickling

pickling将一个python对象转换为一个字节流以便将其存储到文件中或通过网络传输unpickling是将字节流重新转换回原来的python对象
import pickle
data={'A':'b','he':2,'istrue':True}
with open('test.txt','wb') as f:pickle.dump(data,f)
with open('test.txt','rb') as f:data=pickle.load(f)
import json #更安全序列化
with open('data.json','w') as f:json.dump(data,f)
with open('data.json','r') as f:data=json.load(f)

python内存管理机制

python里内存管理主要依赖于自动内存管理机制,特别是垃圾回收机制,python使用引用计数和垃圾回收相结合的方式来管理内存;每个对象的引用次数将为零时python会立即回收相关内存;python内置的垃圾回收器专门处理引用循环的问题。

python程序退出时,不一定能释放所有内存,python的垃圾回收器尝试回收不再使用的内存,但是由于一些引用循环依赖于垃圾回收发现和处理,程序退出时并不保证足够的时间处理所有循环引用;还有一些外部C库的资源管理问题,C库可能分配程序一些内存,python退出时并不负责清理这些外部库分配的内存,需要依赖这些库本身提供的清理机制否则会有内存泄漏,防止内存泄漏可以使用上下文管理器来管理资源,比如使用with open() as file确保文件操作后文件会自动关闭,尽量减少全局变量的使用及时清理不再需要的对象。

python的深拷贝与浅拷贝

浅拷贝:拷贝父对象,不会拷贝对象内部的子对象。深拷贝:拷贝父对象以及对象内部的所有子对象。在Python中,可以使用copy模块来实现浅拷贝和深拷贝。浅拷贝使用copy模块的copy函数:

import copyoriginal_list = [1, 2, [3, 4]]
shallow_copy = copy.copy(original_list)
deep_copy=copy.deepcopy(original_list)
print(original_list)  # 输出: [1, 2, [3, 4]]
print(shallow_copy)  # 输出: [1, 2, [3, 4]]
print(deep_copy)  # 输出: [1, 2, [3, 4]]
original_list[2][0]=0
print(original_list)  # 输出: [1, 2, [0, 4]]
print(shallow_copy)  # 输出: [1, 2, [0, 4]]
print(deep_copy)  # 输出: [1, 2, [3, 4]]

python3 VS python2

打印语句p2里print是语句print”hell“, p3里print变为一个函数print(”hell“)
整数除法p2里5/2=2,  p3里5/2=2.5
字符串p2里默认字符串类型是ASCII,文件编码需要显示声明coding=utf-8,p3是默认类型是Unicode,默认文件编码utf-8
内置函数变化p2里range() 返回一个列表, p3返回迭代器,你需要list(range(2))返回列表
库的改进p3对许多内置库和语法进行改进和简化,提升可读性和性能如urllib, input()函数
异常处理p2写异常except SomeException,e ; p3使用except SomeException as e
数据类型p3增加新数据类型如bytes,处理字节数据,还引进了诸如functools。pathlib
迭代器和生成器p3对迭代器和生成器进一步优化,提高了性能,如map(), filter(),zip()等在p3中返回迭代器,p2里返回时列表

 


http://www.ppmy.cn/server/147337.html

相关文章

【系统架构设计师论文】微服务架构设计与实践

一、微服务架构概述 1.1 什么是微服务架构? 微服务架构(Microservices Architecture)是一种将应用程序拆分为多个小型服务的架构模式,每个服务都可以独立开发、部署、扩展,并通过轻量级的通信协议(通常是 HTTP/REST 或 gRPC)进行交互。这种架构的核心思想是将大型单体…

VScode离线下载扩展安装

在使用VScode下在扩展插件时,返现VScode搜索不到插件,网上搜了好多方法,都不是常规操作,解决起来十分麻烦,可以利用离线下载安装的方式安装插件!亲测有效!!! 1.找到VScod…

2024.12.2工作复盘

1.今天学了什么? 简单的写了一篇博客,是关于参数校验的问题,参数校验,一个是前后端校验到底一不一致,一个是绕过前端校验,看后台的逻辑到底能不能校验住。 2.今天解决了什么问题? 3.今天完成…

Yagmail邮件发送库:如何用Python实现自动化邮件营销?

目录 一、Yagmail简介 二、安装Yagmail 三、基本使用示例 1. 发送简单文本邮件 2. 发送HTML邮件 3. 发送带有附件的邮件 4. 多收件人处理 5. 自定义邮件头 四、高级功能 1. SMTP配置 2. 邮件模板 3. OAuth2认证 五、自动化邮件营销案例 六、错误处理和调试 七、…

unity读取mysql5.7版本示例

使用了miniexcel插件&#xff0c;与mydata.dll 。 using MiniExcelLibs; using MySql.Data.MySqlClient; using System.Collections.Generic; using System.Data; using System.Text; using UnityEngine;public class LoadMySQL_虚拟仿真 : DataLayerBase<Dictionary<st…

【C语言】结构体(四)

本篇重点是typedef关键字 一&#xff0c;是什么&#xff1f; typedef用来定义新的数据类型&#xff0c;通常typedef与结构体的定义配合使用。 简单来说就是取别名 ▶ struct 是用来定义新的数据类型——结构体 ▶ typedef是给数据类型取别名。 二&#xff0c;为什么&#xf…

sscanf与sprintf函数

本期介绍&#x1f356; 主要介绍&#xff1a;sscanf()、sprintf()这对输入/输出函数&#xff0c;并详细讲解了这两个函数的应用场景。 概述&#x1f356; 在C语言的输出和输入库中&#xff0c;有三对及其相似的库函数&#xff1a;printf()、scanf()、fprintf()、fscanf()、spri…

C++入门一

一、命名空间 #include <stdio.h> int rand 0; int main() {printf("hello world\n");printf("%d\n", rand); } 这样是可以运行的&#xff0c;可是当我们加入一个头文件的时候 #include <stdio.h> #include <stdlib.h> int rand 0;…