2024年Python最新【python开发】并发编程(下),2024年最新字节跳动的面试流程

简介: 2024年Python最新【python开发】并发编程(下),2024年最新字节跳动的面试流程
也可以把多进程放在函数里,用main函数来运行。
from multiprocessing import Process
def task(arg):
pass
def run():
p = Process(target=task, args=(‘xxx’, ))
p.start()
if name == ‘__main__’:
run()
在python中基于multiprocessing模块操作的进程,start methods主要有三种:
1. fork:可以拷贝几乎所有资源,支持文件对象/线程锁等传参,unix系统适用,任意位置开始;
2. spwan:run参数必备资源,不支持文件对象/线程锁等传参,unix、win适用,main代码模块开始;
3. forkserver:run参数必备资源,不支持文件对象/线程锁等传参,部分unix适用,main代码模块开始。
### (二)案例
#### 1、示例一:fork模式下复制列表元素到子进程中
先创建一个子进程,然后设置模式为fork,我们可以运行一下子进程,看看线程里的name长什么样,实验结果显示,主线程的name被复制到子进程里。
import multiprocessing
def task():
print(name)
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
p1 = multiprocessing.Process(target=task)
p1.start()

#[]

在子进程里面修改name,增加列表元素,在子进程和主进程里分别打印name观察,可以发现:进程中改变的name并不会影响主进程中的name。
import multiprocessing
import time
def task():
print(name)
#[]
name.append(123)
print(name)
#[123]
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
p1 = multiprocessing.Process(target=task)
p1.start()
time.sleep(2)
print(name)
#[]
但是如果append操作放在主线程里,那么经过append操作的name会被复制到进程中,在子进程中打印name可以发现是多了123元素的列表。
import multiprocessing
import time
def task():
print(name)
#[123]
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
name.append(123)
p1 = multiprocessing.Process(target=task)
p1.start()
#### 2、示例二:spawn模式下复制列表元素到子进程中
切换到spawn模式后,我们可以发现在spawn模式下,name并不能直接复制到进程中,会报错,所以只能当作参数传入到task中。
import multiprocessing
import time
def task(data):
print(data)
#[]
if name == ‘__main__’:
multiprocessing.set_start_method(“spawn”) #fork、spawn、forkserver
name = []
p1 = multiprocessing.Process(target=task, args=(name, ))
p1.start()
同样的,在子进程中对name进行append操作,结果发现子进程中的改变并不会影响主进程中的name。
import multiprocessing
import time
def task(data):
print(data)
#[]
data.append(999)
print(data)
#[999]
if name == ‘__main__’:
multiprocessing.set_start_method(“spawn”) #fork、spawn、forkserver
name = []
p1 = multiprocessing.Process(target=task, args=(name, ))
p1.start()
time.sleep(2)
print(name)
#[]
#### 3、示例三:在fork模式下复制文件对象到子进程中
spawn并不支持特殊对象:文件或锁的传参,而且即使是普通对象也只能通过传参的形式进行传递。
import multiprocessing
import time
def task():
print(name)
#[]
file_object.write(‘闫曦月\n’)
file_object.flush() #高宇星和闫曦月这两个内容已经刷到硬盘中了
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
file_object = open(‘x1.txt’, mode=‘a+’, encoding=‘utf-8’)
file_object.write(‘高宇星\n’)
#写入到内存中,内容还没有写到文件里,在子进程运行完之后才会将该内容刷到硬盘上
p1 = multiprocessing.Process(target=task)
p1.start()
txt的内容是:  
 高宇星  
 闫曦月  
 高宇星
在本案例中,我们创建了一个txt文件,并将高宇星复制到子进程中,子进程在flush的时候把两个数据都写到了硬盘中,最后等子进程运行完之后,主进程再次将高宇星这条数据刷到硬盘中。
import multiprocessing
import time
def task():
print(name)
#[]
file_object.write(‘闫曦月\n’)
file_object.flush()
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
file_object = open(‘x1.txt’, mode=‘a+’, encoding=‘utf-8’)
file_object.write(‘高宇星\n’)
file_object.flush()
p1 = multiprocessing.Process(target=task)
p1.start()


txt的内容是:  
 高宇星  
 闫曦月
这里有不同点,是在主进程里,已经进行了flush,所以已经将内存中的信息高宇星刷到硬盘上了,所以在子进程运行结束之后就不会再刷高宇星到硬盘上了。
#### 4、示例四:在fork模式下复制锁到子进程中
spawn模式下,锁没有办法被传参。
import multiprocessing
import threading
def task():
print(file_object, lock)
#<_io.TextIOWrapper name=‘x1.txt’ mode=‘a+’ encoding=‘utf-8’> 
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
file_object = open(‘x1.txt’, mode=‘a+’, encoding=‘utf-8’)
lock = threading.RLock()
p1 = multiprocessing.Process(target=task)
p1.start()
当我们在主进程中申请了锁之后,主进程中打印出来的锁是已经进行locked过的。
import multiprocessing
import threading
def task():
pass
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
lock = threading.RLock()
print(lock)
#
lock.acquire()
print(lock)
# 
lock.release()
print(lock)
#
lock.acquire()
print(lock)
#
p1 = multiprocessing.Process(target=task)
p1.start()
当我们在主进程中申请了锁之后,子进程中打印出来的锁是已经进行locked过的,是子进程的主线程锁的。
import multiprocessing
import threading
def task():
#拷贝的锁也是申请走的状态,被谁申请走了?被子进程中的主线程申请走了
print(lock)
#
lock.acquire()
print(666)
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
lock = threading.RLock()
#
lock.acquire()
p1 = multiprocessing.Process(target=task)
p1.start()
锁被子进程中的主线程申请走了,所以在子进程中如果创立其他线程的话,其他线程是获取不到锁的,所以程序代码都会卡住,只有将子线程中将主线程的锁进行释放,子进程中其他子线程才会获取到锁并执行下去。
import multiprocessing
import threading
import time
def func():
print(“来了”)
with lock:
    print(666)
    time.sleep(1)
def task():
for i in range(10):
t = threading.Thread(target=func)
t.start()
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
lock = threading.RLock()
#
lock.acquire()
p1 = multiprocessing.Process(target=task)
p1.start()
‘’’
来了
来了
来了
来了
来了
来了
来了
来了
来了
来了
‘’’
#程序卡住了,运行不下去
将子线程中的主线程里的lock锁进行释放后,子线程可以正常执行代码。
import multiprocessing
import threading
import time
def func():
print(“来了”)
with lock:
    print(666)
    time.sleep(1)
def task():
for i in range(10):
t = threading.Thread(target=func)
t.start()
time.sleep(1)
lock.release()
if name == ‘__main__’:
multiprocessing.set_start_method(“fork”) #fork、spawn、forkserver
name = []
lock = threading.RLock()
#
lock.acquire()
p1 = multiprocessing.Process(target=task)
p1.start()
‘’’
来了
来了
来了
来了
来了
来了
来了
来了
来了
来了
666
666
666
666
666
666
666
666
666
666
‘’’
### (三)常见功能
#### 1、p.start()
当前进程准备就绪,等待被CPU调度(工作单元其实就是进程中的线程)
#### 2、p.join()
等待当前进程的任务执行完毕后再向下继续执行
import multiprocessing
from multiprocessing import Process
import threading
import time
def task(arg):
time.sleep(2)
print(“执行中。。。”)
if name == ‘__main__’:
multiprocessing.set_start_method(“spawn”) #fork、spawn、forkserver
p = Process(target=task, args=(‘xxx’, ))
p.start()
p.join()
print("继续执行。。。")
‘’’
执行中。。。
继续执行。。。
‘’’
#### 3、p.daemon()
是布尔值,守护进程(必须放在start之前)
p.daemon = True :设置为守护进程,主进程执行完之后,子进程也自动关闭。  
 p.daemon = False :设置为非守护进程,主进程等待子进程,子进程执行完之后,主进程才结束。
import multiprocessing
from multiprocessing import Process
import threading
import time
def task(arg):
time.sleep(2)
print(“执行中。。。”)
if name == ‘__main__’:
multiprocessing.set_start_method(“spawn”) #fork、spawn、forkserver
p = Process(target=task, args=(‘xxx’, ))
p.daemon = True
p.start()
print("继续执行。。。")
‘’’
继续执行。。。
‘’’
上述代码在执行完主进程之后就自动关闭了,子进程并没有得到执行。
#### 4、进程名称的设置和获取
import multiprocessing
from multiprocessing import Process
import threading
import time
def task(arg):
time.sleep(2)
print(“当前进程的名称:”, multiprocessing.current_process().name)
if name == ‘__main__’:
multiprocessing.set_start_method(“spawn”) #fork、spawn、forkserver
p = Process(target=task, args=(‘xxx’, ))
p.name = ‘new bee’
p.daemon = False
p.start()
print("继续执行。。。")
‘’’
继续执行。。。
当前进程的名称: new bee
‘’’
#### 5、自定义进程类
将进程定义为类,直接僵线程需要做的事儿写到run方法中
import multiprocessing
class MyProcess(multiprocessing.Process):
def run(self):
print(‘执行此进程’, self._args)
if name == ‘__main__’:
multiprocessing.set_start_method(‘spawn’)
p = MyProcess(args=(‘xxx’, ))
p.start()
print(“继续执行”)
‘’’
继续执行
执行此进程 (‘xxx’,)
‘’’
#### 6、获取进程和子进程id号
import multiprocessing
from multiprocessing import Process
import threading
import time
import os
def func():
time.sleep(1)
def task(arg):
for i in range(10):
t = threading.Thread(target=func)
t.start()
#time.sleep(2)
print(os.getpid(), os.getppid())
print(“当前进程的名称:”, multiprocessing.current_process().name)
print(len(threading.enumerate())) #获取线程个数
#11
if name == ‘__main__’:
print(os.getpid())
multiprocessing.set_start_method(“spawn”) #fork、spawn、forkserver
p = Process(target=task, args=(‘xxx’, ))
p.name = ‘new bee’
p.daemon = False
p.start()
print("继续执行。。。")
‘’’
8517 主进程id号
继续执行。。。
当前进程的名称: new bee
8558 子进程id号
8554 副进程id号
11
‘’’
#### 7、cpu的个数
为了利用cpu多核优势,一般需要看看有多少个cpu,定义相同数量的进程
import multiprocessing
print(multiprocessing.cpu_count())
#4
## 二、进程间数据的共享
进程是资源分配的最小单元,每个进程中都维护自己独立的数据,不共享。如果想要进程之间的数据进行共享,可以借助一些中介来实现。
当我们在子进程中修改列表数据时,主进程中的列表数据并没有发生变化,说明主进程和子进程之间是割裂的,数据并不共享。
import multiprocessing
def task(data):
data.append(666)
print(data) #[666]
if name == “__main__”:
data_list = []
p = multiprocessing.Process(target=task, args=(data_list,))
p.start()
p.join()
print("主进程:", data_list)
#主进程: []
### (一)共享
#### 1、share memory: Value / Array
通过Value和Array在子进程中更改元素的变量值,改变后的值同样也能共享到主进程中
字母所代表的含义:  
 ![请添加图片描述](https://ucc.alicdn.com/images/user-upload-01/direct/1fbc70a3391144f3ae42395040c9b871.jpeg)
from multiprocessing import Process, Value, Array
def func(n, m1, m2):
n.value = 888
m1.value = ‘a’.encode(‘utf-8’)
m2.value = “武”
if name == ‘__main__’:
num = Value(‘i’, 666)
v1 = Value(‘c’)
v2 = Value(‘u’)
p = Process(target=func, args=(num, v1, v2))
p.start()
p.join()
print(num.value) #888
print(v1.value) #a
print(v2.value) #武
Array可以更改数组的元素值
from multiprocessing import Process, Value, Array
def func(data_array):
data_array[0] = 666
if name == ‘__main__’:
arr = Array(‘i’, [11, 22, 33, 44, 55, 66]) #数组:元素类型必须是int
p = Process(target=func, args=(arr, ))
p.start()
p.join()
print(arr[:])
#[666, 22, 33, 44, 55, 66]
#### 2、Manager()
通过Manager来更改列表、字典的值
from multiprocessing import Process, Manager
def func(d, l):
d[‘高宇星’] = ‘18岁’
d[‘闫曦月’] = ‘68岁’
d[0.25] = None
l.append(666)
if name == ‘__main__’:
with Manager() as manager:
d = manager.dict()
l = manager.list()
p = Process(target=func, args=(d, l))
    p.start()
    p.join()
    print(d) #{'高宇星': '18岁', '闫曦月': '68岁', 0.25: None}
    print(l) #[666]
### (二)交换
#### 1、Queue
通过Queue将数据进行排队处理  
 ![请添加图片描述](https://ucc.alicdn.com/images/user-upload-01/direct/a741c797d714467abcc877f6b7e299b4.png)
import multiprocessing
def task(q):
for i in range(10):
q.put(i)

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。


相关文章
|
6天前
|
JSON 数据可视化 数据处理
Python基础第九篇(Python可视化的开发)
Python基础第九篇(Python可视化的开发)
|
2天前
|
数据采集 机器学习/深度学习 数据可视化
利用Python和Pandas库构建高效的数据分析流程
在数据驱动的时代,数据分析已成为企业决策的关键环节。本文介绍如何利用Python编程语言及其强大的数据分析库Pandas,构建一套高效且可扩展的数据分析流程。与常规的数据分析流程不同,本文不仅涵盖数据加载、清洗、转换等基础步骤,还强调数据可视化、模型探索与评估等高级分析技巧,并通过实际案例展示如何在Python中实现这些步骤,为数据分析师提供一套完整的数据分析解决方案。
|
2天前
|
数据采集 机器学习/深度学习 数据挖掘
利用Python实现高效的数据清洗与预处理流程
本文旨在探讨如何使用Python编程语言及其强大的数据处理库(如pandas、numpy等)来构建一个高效且灵活的数据清洗与预处理流程。与常规的数据清洗方法不同,本文不仅关注于传统的缺失值填充、异常值处理、数据类型转换等步骤,还引入了数据质量评估、数据特征选择以及自动化处理流程的设计等高级主题。通过实际案例和代码演示,本文将为读者提供一套完整的数据清洗与预处理解决方案,助力数据分析师和数据科学家在数据探索阶段更加高效、准确地处理数据。
|
6天前
|
人工智能 数据可视化 数据挖掘
10个提高Python开发效率的工具
10个提高Python开发效率的工具
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
豆瓣评分9.5!清华大牛熬夜整理的Python深度学习教程开发下载!
深度学习目前已经成为了人工智能领域的突出话题。它在“计算机视觉和游戏(AlphaGo)等领域的突出表现而闻名。 今天给小伙伴们分享的这份手册,详尽介绍了用 Python 和 Keras进行深度学习的探索实践,涉及计算机视觉、自然语言处理、生成式模型等应用。
|
5天前
|
网络安全 网络虚拟化 数据安全/隐私保护
使用Python实现VPN搭建的流程步骤
保护个人隐私和数据安全变得尤为重要。VPN(虚拟私人网络)是一种有效的解决方案,可以帮助我们在网络上匿名浏览,保护数据传输的安全性。虽然市面上有许多商业VPN服务,但你也可以通过Python自己搭建一个简单的VPN。本文将介绍如何用Python建立自己的VPN。
|
7天前
|
存储 数据挖掘 索引
Python streamlit框架开发数据分析网站并免费部署
使用Python的Streamlit框架,开发了一个在线数据分析工具,替代Excel查看设备温度CSV数据。通过pandas读取数据,matplotlib绘制图表。程序处理CSV,提取所需列,计算最大最小平均值,用户可多选查看特定数据。[GitHub](https://github.com/yigedaigua/MGHB)上有完整代码,应用已部署至Streamlit Cloud。
|
3天前
|
安全 前端开发 Java
杨校老师课堂之Spring Boot框架面试题【开发工程师面试前必看】
杨校老师课堂之Spring Boot框架面试题【开发工程师面试前必看】
13 0
|
1天前
|
机器学习/深度学习 人工智能 前端开发
Python中的模块化编程
【6月更文挑战第17天】Python模块化编程与软件架构设计的关键在于拆分任务到独立模块,提高代码的可维护性、可重用性和可扩展性。例如,学生管理系统可分解为录入、查询和删除模块。MVC和MVVM架构模式有助于组织代码,而微服务和函数式编程将在未来发展中扮演重要角色。通过示例代码,读者能学习如何实现这些概念,提升项目开发效率和质量。
147 57
|
9天前
|
测试技术 虚拟化 云计算
GitHub高赞!速通Python编程基础手册,被玩出花了!
随着云时代的来临,Python 语言越来越被程序开发人员喜欢和使用,因为其不仅简单易学,而且还有丰富的第三方程序库和相应完善的管理工具。 从命令行脚本程序到 GUI程序,从图形技术到科学计算,从软件开发到自动化测试,从云计算到虚拟化,所有这些领域都有 Python 的身影。 今天给小伙伴们分享的这份手册采用以任务为导向的编写模式,全面地介绍了 Python 编程基础及其相关知识的应用,讲解了如何利用 Python 的知识解决部分实际问题。
GitHub高赞!速通Python编程基础手册,被玩出花了!