作为数据科学家你应该知道这些 python 多线程、进程知识

Python FastAPI 多线程与异步编程的结合 在当今的 Web 开发中,高并发处理能力是一个关键需求。FastAPI 作为一个快速、现代的 Python Web 框架,为开发者提供了强大的异步编程支持。然而,有些任务可能并不适合异步处理,比如一些 CPU 密集型任务。此时,多线程就可以发挥作用。本文的目的就是探讨如何在 FastAPI 中有效地结合多线程和异步编程,以实现更高效的并发处理。范围涵盖了从基本概念的介绍到实际项目中的应用,以及相关工具和资源的推荐。本文将按照以下结构进行阐述:首先介绍核心概念,包括多线程和异步编程的原理和联系; 阅读详情

每个数据科学项目迟早都会面临一个不可避免的挑战:速度问题。使用更大的数据集会导致处理速度变慢,因此最终必须想办法优化算法的运行时间。正如你们大多数人已经知道的,并行化是这种优化的必要步骤。python 为并行化提供了两个内置库:多处理和线程。在这篇文章中,我们将探讨数据科学家如何在两者之间进行选择,以及在这样做时应注意哪些因素。

并行计算与数据科学

众所周知,数据科学是处理大量数据并从中提取有用见解的科学。通常情况下,我们对数据执行的操作很容易并行化,这意味着不同的处理代理可以一次对数据执行一个操作,最后进行组合以获得完整的结果。

为了更好地解释并行性,让我们拿一个真实世界的例子作为类比。假设你需要打扫你家的三个房间。你可以自己打扫,打扫完一个再打扫另一个,也可以让你的两个兄弟姐妹帮你打扫,每个人打扫一个房间。在后一种方法中,每个人完成整个任务的一部分,从而减少了完成任务所需的总时间。这就是实际中的并行性。

并行处理可以用 python 以两种不同的方式实现:多处理和线程。

多处理与线程:理论

基本上,多处理和线程是实现并行计算的两种方法,分别使用进程和线程作为处理代理。为了理解它们的工作原理,我们必须搞清楚什么是进程和线程。

进程

进程是正在执行的计算机程序的实例。每个进程都有自己的内存空间,用来存储正在运行的指令,以及需要存储和访问才能执行的任何数据。

线程

线程是进程的组件,可以并行运行。一个进程中可以有多个线程,它们共享相同的内存空间,即父进程的内存空间。这意味着要执行的代码以及程序中声明的所有变量将由所有线程共享。

例如,让我们回想一下正在你的计算机上运行的程序。你可能正在浏览器中阅读本文,浏览器可能打开了多个选项卡。你也可以同时通过 Spotify 桌面应用程序收听音乐。浏览器和 spotify 应用程序是不同的进程;每个进程都可以使用多个进程或线程来实现并行性。浏览器中的不同选项卡可能在不同的线程中运行。Spotify 可以在一个线程中播放音乐,在另一个线程中从 Internet 下载音乐,并使用第三个线程显示图形用户界面。这称为多线程。对多个进程进行多处理也可以做到这一点。事实上,像 chrome 和 firefox 这样的大多数现代浏览器使用多处理,而不是多线程来处理多个选项卡。

技术细节

一个进程的所有线程都存在于同一个内存空间中,而进程有各自的内存空间。

与进程相比,线程更轻量级,开销更低。生成进程比生成线程慢一点。

在线程之间共享对象更容易,因为它们共享相同的内存空间。为了实现同一个进程间通信,我们必须使用某种 IPC (inter-process communication) 模型,它通常由 OS 提供。

并行计算的陷阱

将并行性引入程序并不总是一个正和博弈,也有一些陷阱需要注意。其中,最重要的是下面的这些问题。

竞争条件:正如我们已经讨论过的,线程有一个共享内存空间,因此它们可以访问共享变量。当多个线程试图同时更改同一个变量时,会出现竞争条件。线程调度程序可以在线程之间任意交换,因此我们无法知道线程尝试更改数据的顺序。这可能会导致两个线程中的任何一个出现不正确的行为,特别是当线程决定基于变量的值执行某些操作时。为了防止这种情况发生,可以在修改变量的代码段周围放置互斥锁,以便一次只能有一个线程写入变量。

饥饿:当一个线程在较长时间内被拒绝访问某个特定的资源时,就会发生饥饿,在这种情况下,整个程序的速度会减慢。这可能是由于线程调度算法设计不当而产生的意外副作用。

死锁:过度使用互斥锁也有一个缺点——它会在程序中引入死锁。死锁是一个线程等待另一个线程释放锁时的状态,但另一个线程需要一个资源来完成第一个线程保持的操作。这样,两个线程都会停止,程序也会停止。死锁可以被认为是饥饿的极端情况。为了避免这种情况,我们必须小心不要引入太多相互依赖的锁。

活锁:活锁是指线程在循环中继续运行,但没有任何进展。这也是由于互斥锁设计不当和使用不当造成的。

python 中的多处理和线程

全局解释器锁

说到 python,有一些奇怪的地方需要记住。我们知道线程共享相同的内存空间,因此必须采取特殊的预防措施,以便两个线程不会写入相同的内存位置。CPython 解释器使用名为 GIL 的机制或全局解释器锁来处理这个问题。

python wiki 上面的资料:

在 CPython 中,全局解释器锁(GIL)是一个互斥锁,它保护对 python 对象的访问过程,防止多个线程同时执行 python 字节码。这个锁是必要的,这主要是因为 CPython 的内存管理不是线程安全的。

了解 python GIL 的详细信息,请查看:https://www.dabeaz.com/python/UnderstandingGIL.pdf 。

GIL 完成了任务,但付出了代价。它在解释器级别上有效地序列化指令。其工作原理如下:任何线程要执行任何函数,都必须获取全局锁。一次只有一个线程可以获取该锁,这意味着解释器最终会以串行方式运行指令。这种设计使得内存管理线程安全,但结果是,它根本不能利用多个 cpu 内核。在单核 cpu 中,这不是什么大问题。但是如果你使用多核 cpu,这个全局锁最终会成为一个瓶颈。

但是,如果你的程序在其他地方(例如在网络、IO 或用户交互中)有更严重的瓶颈,则此瓶颈将变得无关紧要。在这些情况下,线程是一种完全有效的并行化方法。但对于 CPU 受限的程序,线程最终会使程序变慢。让我们通过一些示例用例来探讨这个问题。

线程的使用案例

GUI 程序始终使用线程来使应用程序响应。例如,在文本编辑程序中,一个线程负责记录用户输入,另一个线程负责显示文本,第三个线程负责拼写检查,等等。在这里,程序必须等待用户交互,这是最大的瓶颈。使用多处理不会使程序更快。

线程的另一个用例是 io 绑定或网络绑定的程序,例如 web-scrapers。在这种情况下,多个线程可以同时处理多个网页的刮擦。线程必须从 Internet 下载网页,这将是最大的瓶颈,因此线程是一个完美的解决方案。Web 服务器是受网络约束的,工作原理与此类似;有了它们,多处理就没有线程的优势了。另一个相关的例子是 tensorflow,它使用线程池并行地转换数据。

多处理的使用案例

如果程序是 CPU 密集型的,并且不需要进行任何 IO 或用户交互,那么多处理就比线程更加突出。例如,任何一个只处理数字的程序都可以使用多处理得到极大的加速;事实上,线程可能会减慢它的速度。一个有趣的实际例子是 Pytorch Dataloader,它使用多个子进程将数据加载到 GPU 中。

python 中的并行化

python 为同名的并行化方法提供了两个库——多处理和线程。尽管它们之间有着根本的区别,但这两个库提供了非常相似的 API(从 python 3.7 开始)。让我们来具体看看吧。

import threadingimport randomfrom functools import reducedef func(number): random_list = random.sample(range(1000000), number) return reduce(lambda x, y: x*y, random_list)number = 50000thread1 = threading.Thread(target=func, args=(number,))thread2 = threading.Thread(target=func, args=(number,))thread1.start()thread2.start()thread1.join()thread2.join()

你可以看到,我创建了一个函数 func,它创建一个随机数列表,然后按顺序将其所有元素相乘。如果物品数量足够大,比如说 5 万或 10 万件,这可能是一个相当繁重的过程。

然后,我创建了两个线程来执行同一个函数。线程对象有一个异步启动线程的 start 方法。如果我们想等待它们终止并返回,我们必须调用 join 方法,这就是我们在上面所做的。

如你所见,在后台将新线程转到任务的 API 非常简单。最棒的是,用于多处理的 API 也几乎完全相同;让我们来检查一下吧~

import multiprocessingimport randomfrom functoolsimport reducedef func(number): random_list = random.sample(range(1000000), number) return reduce(lambda x, y: x*y, random_list)number = 50000process1 = multiprocessing.Process(target=func, args=(number,))process2 = multiprocessing.Process(target=func, args=(number,))process1.start()process2.start()process1.join()process2.join()

在这里它只是交换线程。有着多处理的线程。

显然,你可以用它做很多事情,但这不在本文的范围内,所以我们不在这里讨论。如果你有兴趣了解更多信息,请查看这里和这里的文档:https://docs.python.org/3/library/threading.html 和 https://docs.python.org/3/library/threading.html 。

基准点

现在我们已经了解了实现并行化的代码是什么样子的,让我们回到性能问题上来。如前所述,线程不适合用于 CPU 限制的任务;在这些情况下,它最终成为一个瓶颈。我们可以使用一些简单的基准来验证这一点。

首先,让我们看看在我上面展示的代码示例中,线程处理与多处理是如何比较的。请记住,此任务不涉及任何类型的 IO,因此它是纯 CPU 绑定的任务。

让我们看看一个 IO 绑定任务的类似基准。例如,以下函数:

import requestsdef func(number): url = 'http://example.com/' for i in range(number): response = requests.get(url) with open('example.com.txt', 'w') as output: output.write(response.text)

这个函数只是获取一个网页并将其保存到一个本地文件中,循环多次。无用但直截了当,因此很适合演示。让我们看看基准是什么吧。

现在,从这两张图表中可以注意到以下几点:

在这两种情况下,单个进程的执行时间都比单个线程长。显然,进程比线程有更多的开销。

对于受 CPU 限制的任务,多个进程的性能比多个线程要好。然而,当我们使用 8x 并行化时,这种差异就变得不那么明显了。由于我的笔记本电脑中的处理器是四核的,因此最多有四个进程可以有效地使用多核。所以当我使用更多的进程时,它的伸缩性就不好。但是,它仍然比线程性能好很多,因为线程根本不能利用多个核。

对于 IO 绑定的任务,瓶颈不是 CPU。因此,GIL 带来的通常限制在这里不适用,多处理也没有优势。不仅如此,线程的轻量级开销实际上使它们比多处理更快,并且线程始终优于多处理。

差异、优缺点

线程在相同的内存空间中运行;进程有单独的内存。

1.从前面的观点来看:在线程之间共享对象更容易,但与此同时,你必须采取额外的措施来实现对象同步,以确保两个线程不会同时写入同一个对象,并且不会出现争用情况。

2.由于对象同步增加了编程开销,多线程编程更容易出现错误。另一方面,多进程编程很容易实现。

3.与进程相比,线程的开销更低;生成进程比线程花费更多的时间。

4.由于 python 中 GIL 的局限性,线程不能利用多个 CPU 核实现真正的并行。多处理没有任何这样的限制。

5.进程调度由操作系统处理,而线程调度则由 python 解释器完成。

6.子进程是可中断和可终止的,而子线程不是。你必须等待线程终止或加入。

从所有这些讨论中,我们可以得出以下结论:

1.线程应该用于涉及 IO 或用户交互的程序。

2.多处理应该用于 CPU 受限、计算密集型的程序。

从数据科学家的角度

典型的数据处理管道可分为以下步骤:

1.读取原始数据并存储到主存储器或 GPU 中;

2.使用 CPU 或 GPU 进行计算;

3.将挖掘出的信息存储在数据库或磁盘中。让我们来探索如何在这些任务中引入并行性,从而加快它们的速度。

步骤 1 包括了从磁盘读取数据,因此很明显磁盘 IO 将成为此步骤的瓶颈。正如我们所讨论的,线程是并行这种操作的最佳选择。同样,步骤 3 也是引入线程的理想候选步骤。

但是,步骤 2 包含涉及 CPU 或 GPU 的计算。如果是基于 CPU 的任务,那么使用线程将毫无用处;相反,我们必须进行多处理。只有这样,我们才能利用 CPU 的多个核并实现并行性。如果这是一个基于 GPU 的任务,因为 GPU 已经在硬件级别实现了一个大规模并行化的体系结构,那么使用正确的接口(库和驱动程序)与 GPU 交互应该可以处理剩下的事情。

现在你可能会想,「我的数据管道看起来与此有些不同;我有一些任务并不真正适合这个通用框架。」不过,在这里你应该考虑的因素是:

1.你的任务是否有任何形式的 IO

2.IO 是否是程序的瓶颈

3.你的任务是否取决于 CPU 的大量计算

考虑到这些因素,再加上上面的要点,你应该能够做出决定。另外,请记住,你不必在整个程序中使用单一形式的并行,而是应该在程序的不同部分使用不同的并行。

现在我们来看看数据科学家可能面临的两个常见场景,以及如何使用并行计算来加速它们。

场景 1:下载电子邮件

假设你想分析自己创业公司收件箱中的所有电子邮件,并了解其趋势:谁是最频繁的发件人,电子邮件中出现的最常见关键字是什么,一周中的哪一天或一天中的哪一小时收到的电子邮件最多,等等。当然,这个项目的第一步是将电子邮件下载到你的计算机上。

首先,让我们按顺序进行,而不使用任何并行化。下面是要使用的代码,应该非常简单明了。有一个下载电子邮件的功能,它以电子邮件 ID 列表作为输入,并按顺序下载它们。这个函数一次调用 100 个电子邮件的 ID 列表。

import imaplibimport timeIMAP_SERVER = 'imap.gmail.com'USERNAME = 'username@gmail.com'PASSWORD = 'password'def download_emails(ids): client = imaplib.IMAP4_SSL(IMAP_SERVER) client.login(USERNAME, PASSWORD) client.select() for i in ids: print(f'Downloading mail id: {i.decode()}') _, data = client.fetch(i, '(RFC822)') with open(f'emails/{i.decode()}.eml', 'wb') as f: f.write(data[0][1]) client.close() print(f'Downloaded {len(ids)} mails!')start = time.time()client = imaplib.IMAP4_SSL(IMAP_SERVER)client.login(USERNAME, PASSWORD)client.select()_, ids = client.search(None, 'ALL')ids = ids[0].split()ids = ids[:100]client.close()download_emails(ids)print('Time:', time.time() - start)

所用时间:35.65300488471985 秒。

现在让我们在这个任务中引入一些并行性来加快速度。在开始编写代码之前,我们必须在线程和多处理之间做出决定。正如你目前所了解到的,当任务的瓶颈是 IO 时,线程是最好的选择。这里的任务显然属于这一类,因为它正在通过 Internet 访问 IMAP 服务器。所以我们要开始使用线程了。

我们将要使用的大部分代码将与我们在顺序案例中使用的代码相同。唯一不同的是,我们将把 100 个电子邮件 ID 的列表分成 10 个较小的块,每个块包含 10 个 ID,然后创建 10 个线程,并使用每个线程的不同块调用 download_emails 函数。我正在使用 python 标准库中的 concurrent.futures.threadpoolexecutor 类进行线程处理。

import imaplibimport timefrom concurrent.futures import ThreadPoolExecutorIMAP_SERVER = 'imap.gmail.com'USERNAME = 'username@gmail.com'PASSWORD = 'password'def download_emails(ids): client = imaplib.IMAP4_SSL(IMAP_SERVER) client.login(USERNAME, PASSWORD) client.select() for i in ids: print(f'Downloading mail id: {i.decode()}') _, data = client.fetch(i, '(RFC822)') with open(f'emails/{i.decode()}.eml', 'wb') as f: f.write(data[0][1]) client.close()start = time.time()client = imaplib.IMAP4_SSL(IMAP_SERVER)client.login(USERNAME, PASSWORD)client.select()_, ids = client.search(None, 'ALL')ids = ids[0].split()ids = ids[:100]client.close()number_of_chunks = 10chunk_size = 10executor = ThreadPoolExecutor(max_workers=number_of_chunks)futures = []for i in range(number_of_chunks): chunk = ids[i*chunk_size:(i+1)*chunk_size] futures.append(executor.submit(download_emails, chunk))for future in concurrent.futures.as_completed(futures): passprint('Time:', time.time() - start)

所用时间:9.841094255447388 秒。

如你所见,线程大大加快了它的速度。

场景 2:使用 scikit learn 进行分类

假设你有一个分类问题,你想使用一个随机森林分类器。由于这是一种标准的、众所周知的机器学习算法,我们不需要重新发明轮子,而只需使用 RandomForestClassifier 即可。

以下代码用于演示。我使用助手函数 sklearn.datasets.make_classification 创建了一个分类数据集,然后在此基础上训练了一个 RandomForestClassifier。另外,我正在计时代码中完成模型拟合核心工作的部分。

from sklearn.ensemble import RandomForestClassifierfrom sklearn import datasetsimport timeX, y = datasets.make_classification(n_samples=10000, n_features=50, n_informative=20, n_classes=10)start = time.time()model = RandomForestClassifier(n_estimators=500)model.fit(X, y)print('Time:', time.time()-start)

任务花费时间:34.17733192443848 秒。

现在我们将研究如何减少该算法的运行时间。我们知道这个算法可以在一定程度上并行化,但是什么样的并行化才是合适的呢?它没有任何 IO 瓶颈,相反,它是一个非常 CPU 密集型的任务。所以多处理是合乎逻辑的选择。

幸运的是,sklearn 已经在这个算法中实现了多处理,我们不必从头开始编写它。正如你在下面的代码中看到的,我们只需要提供一个参数 n_jobs(它应该使用的进程数)来启用多处理。

from sklearn.ensemble import RandomForestClassifierfrom sklearn import datasetsimport timeX, y = datasets.make_classification(n_samples=10000, n_features=50, n_informative=20, n_classes=10)start = time.time()model = RandomForestClassifier(n_estimators=500, n_jobs=4)model.fit(X, y)print('Time:', time.time()-start)

所用时间:14.576200723648071 秒。

正如预期的那样,多处理使其速度更快。

结论

大多数(如果不是所有的)数据科学项目将会发现并行计算能大幅提高计算速度。事实上,许多流行的数据科学库已经内置了并行性,你只需启用它即可。因此,在尝试自己实现它之前,请查看正在使用的库的文档,并检查它是否支持并行性。如果没有,本文将帮助你自己实现它。

分享

python的学习书籍资料与进阶视频资料。

百度网盘资源

链接:https://pan.baidu.com/s/1RwIQHPPef9JB_S58tSsYbw
提取码:lpbj

总结

他山之石,可以攻玉。你不努力,永远不会有人对你公平,只有你努力了,有了资源,有了话语权以后,你才可能为自己争取公平的机会。从2014年起,python一路披荆斩棘,走上神坛,而其他语言VisualBasia,c#等排名有下滑。正如《琅琊榜》中的诗句所言:“遥映人间冰雪样,暗香幽浮曲临江。遍识天下英雄路,俯首江左有梅郎”。时势造英雄,现今AI有Python。如果大家对python感兴趣,可以长按扫描下方的二维码。   

                                                                          
  

从时序迷宫到稳定通信:FSMC配置中的时间参数深度解析与实战避坑指南 本文深入解析STM32 FSMC配置中的时间参数,特别是AddressSetupTime和DataSetupTime的实战配置技巧。通过STM32F407连接SRAM的实际案例,提供从理论计算到CubeMX配置的全流程指南,帮助开发者避免常见时序陷阱,确保稳定通信。 阅读详情

相关推荐

Fleury算法寻找欧拉回路(mtlab代码详解)

【代码】Fleury算法寻找欧拉回路(mtlab代码详解)

m0_63449998的博客 1295

《Python实战进阶》No44: 并发框架:concurrent.futures 的使用(下)

`concurrent.futures` 是 Python 标准库中简化并发编程的核心工具,通过 **线程池(ThreadPoolExecutor)** 和 **进程池(ProcessPoolExecutor)** 实现高效的并发任务调度。本篇结合实战案例,在上集中,我们结合 Future 对象和回调机制,通过两个实战案例”API 请求并发处理”,“矩阵运算并行化“展示如何通过上下文管理器优雅地管理资源。在本文,我们将巩固所学知识,演示如何通过 `submit()`、`map()` 等方法并行化处理 I/O

yweng18的博客 1961

基于立创EDA的8口全千兆POE交换机设计详解:RTL8370N芯片与90W大功率供电方案

本文详细解析了基于立创EDA设计的8口全千兆POE交换机方案,核心采用RTL8370N交换芯片与支持90W大功率供电的IEEE 802.3bt标准PD芯片。文章深入探讨了PSE/PD供电管理、电源架构设计、电路细节及关键散热方案,为DIY或学习POE交换机硬件设计提供了完整的开源实践指南。

weixin_29050829的博客 1万+

Python 中的多进程与线程 每个数据科学家都需要知道

本文最初发布于 FLOYDHUB 博客,经原作者 Sumit Ghosh 授权由 InfoQ 中文站翻译并分享。 导读:线程和进程都是现在计算机领域比较时髦的用语。进程 (Process) 是计算机中已运行程序的实体。进程本身不会运行,是线程的容器。程序本身只是指令的集合,进程才是程序(那些指令) 的真正运行。若干进程有可能与同一个程序相关系,且每个进程皆可以同步(循序) 或不同步(平行) 的方...

776

MCGS 和 200SMART 时间同步

在实际应用中,PLC经常会因为断电原因,导致时间不准确。假设我们设置了一个投加泵,每天8-18点投加。屏幕上显示的时间和PLC内部的时间,很可能不一样。所以需要在触摸屏上读取PLC的时间,并且提供设置功能。

mmxxoo_xxmmp的博客 1519

博流BL602开发二 环境搭建与固件烧录实战

本文详细介绍了博流BL602 RISC-V芯片开发环境的搭建与固件烧录全流程。从Linux/WSL系统选择、RISC-V工具链配置、SDK获取,到编译首个Wi-Fi示例并生成固件镜像,再到通过命令行或图形化工具完成烧录及串口测试,提供了完整的实战指南和常见问题解决方案。

weixin_29175469的博客 449

python 并行处理介绍

1.GIL介绍: GIL(Global Interpreter Lock)又称全局解释器锁,是在CPython解释器下的一个独有问题(该问题只针对CPython,其他解释器下并没有)。在CPython解释器下处理多线程问题时,每个线程在执行时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用CPU,也就是说多线程并不是真正意义上的同时执行。 2.multipro...

Boogyman的博客 1863

让 AI 学会“慢思考”:MCP Sequential Thinking 深度部署与使用指南

摘要: MCP Sequential Thinking 是一种让AI具备"慢思考"能力的技术,通过动态调整思维路径解决复杂问题。本文详细介绍了在Windows、macOS和Linux系统下的部署方法,包括环境准备、配置文件修改等步骤。该技术通过"产生想法-评估需求-修正路径"的循环机制,显著提升AI在代码设计、数学证明等复杂任务中的表现。文章还提供了验证安装方法、使用示例和常见问题解答,帮助开发者解锁AI的深层思考能力。(149字)

weixin_43236925的博客 1907

机器学习并行化(parallel machine learning)

最近实习任务除了用公司内部机器学习平台(tensorflow引擎)跑模型就是调研一下浅层机器学习算法的并行与分布式,稍微做个总结 浅层机器学习中能够应用并行或者分布式的方面 1.1 ModelAssessment with Cross validation 相信对机器学习比较熟的都经常用交叉验证,简单解释一下就是把样本划分为n块相同大小的,选一些出来做训练集,剩下的做验证集,比较常见的是就留

u013818406的博客 1万+

ZYQN7000系列VxWorks驱动开发:VxWorks系统移植

文章目录ZYQN7000驱动开发:VxWorks系统移植1.硬件环境2.编译vsb和vip工程2.1修改设备树文件2.2添加调试打印组件3.选择uboot来启动VxWorks内核4.尝试在开发板上启动内核4.1 拷贝镜像和设备树至SD卡4.2开发板上电4.2.1 uboot成功启动4.2.2 启动VxWorks5.添加shell和cmd组件 ZYQN7000驱动开发:VxWorks系统移植 1.硬件环境 正点原子领航者开发板 2.编译vsb和vip工程 vsb和vip工程的编译过程可以参考之前的文章,htt

明故宫的记忆 5504

实现画布拖拽算子排布,通过flink实现算子编排计算,如何实现?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1070

concurrent.futures 使用及解析

from concurrent.futures import ThreadPoolExecutor, as_completed, wait, FIRST_COMPLETED from concurrent.futures import Future from multiprocessing import Pool #未来对象,task的返回容器 #线程池, 为什么要线程池 ...

weixin_33759269的博客 754

基于STM32+ESP8266+手机APP的心率血氧温湿度监测报警系统设计(项目资料ID:18)

基于 STM32 微控制器、ESP8266 无线模块和 QT 手机 APP 的多参数监测报警系统。该系统可实时采集心率、血氧饱和度、环境温湿度等参数,通过 OLED 显示屏本地显示,并通过 WiFi 模块上传至手机 APP 实现远程监测与数据可视化。系统具备报警阈值自定义功能,当参数超出设定范围时,通过蜂鸣器和 LED 进行声光报警。系统以 STM32F103 为控制核心,采用 MAX30102 传感器采集心率和血氧,DHT20 采集温湿度,通过 ESP8266 实现无线通信,配合 QT 开发的手机 APP

以培养嵌入式工程师为己任 1万+

python数据驱动加多线程_想提高计算速度?作为数据科学家你应该知道这些 python 多线程、进程知识...

每个数据科学项目迟早都会面临一个不可避免的挑战:速度问题。使用更大的数据集会导致处理速度变慢,因此最终必须想办法优化算法的运行时间。正如你们大多数人已经知道的,并行化是这种优化的必要步骤。python 为并行化提供了两个内置库:多处理和线程。在这篇文章中,我们将探讨数据科学家如何在两者之间进行选择,以及在这样做时应注意哪些因素。并行计算与数据科学众所周知,数据科学是处理大量数据并从中提取有用见解的...

weixin_39946460的博客 197

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

python计算数据百分比_想提高计算速度?作为数据科学家你应该知道这些 python 多线程、进程知识...

每个数据科学项目迟早都会面临一个不可避免的挑战:速度问题。使用更大的数据集会导致处理速度变慢,因此最终必须想办法优化算法的运行时间。正如你们大多数人已经知道的,并行化是这种优化的必要步骤。python 为并行化提供了两个内置库:多处理和线程。在这篇文章中,我们将探讨数据科学家如何在两者之间进行选择,以及在这样做时应注意哪些因素。并行计算与数据科学众所周知,数据科学是处理大量数据并从中提取有用见解的...

weixin_39867662的博客 172

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

python多线程并发编程技术_Python并发简介

在本章中,我们将理解Python中的并发概念,并了解线程和进程的区别。什么是并发?简而言之,并发是指同时发生两个或多个事件。 并发是一种自然现象,因为许多事件在任何给定的时间同时发生。就编程而言,并发是两个任务在执行过程中重叠的时候。 通过并发编程,我们的应用程序和软件系统的性能可以得到提高,因为我们可以同时处理请求,而不是等待前一个完成再处理下一个。并发性的历史回顾以下几点将给我们简要的并发历史...

weixin_39922769的博客 99

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【效率起飞】Python 数据科学家必备的神仙库,别再只知道 Pandas 和 NumPy 了

工具的上限,往往决定了你产出的下限。从 Pandas 到 Polars,从 GridSearch 到 Optuna,升级你的工具箱,把脏活累活交给底层优化引擎,把宝贵的时间留给对业务的思考和算法架构的设计。

m0_69378371的博客 388

AI服务的并发处理【Python】

有一段时间,我专注于机器学习的研究方面,为不同的任务开发定制的机器学习解决方案。但是最近,新项目进来了,有时自己负责初始部署比寻求其他开发人员的帮助更快。我发现了几个在规模、易用性、定价等方面不同的部署选项。今天,我们将讨论一种简单而强大的机器学习模型部署方法。它允许我们同时处理多个请求并在需要时扩展应用程序。我们还将讨论数据科学家在将机器学习模型投入生产时的职责,以及如何使用一些方便的 Python 工具对 Web 应用程序进行负载测试。推荐:用快速搭建可编程3D场景。

新缸中之脑 2018

Awesome Data Science with Python:数据科学家的必备宝典

你是否曾经在数据科学项目中陷入这样的困境?面对海量数据却不知从何下手,需要实现复杂分析却找不到合适的工具,或者想要优化性能但缺乏有效的解决方案。数据科学领域日新月异,每天都有新的库和工具涌现,如何在这个快速发展的生态系统中保持竞争力? 本文将为你呈现一份全面的Python数据科学资源宝典,涵盖从数据处理到机器学习,从可视化到部署的完整工具链。无论你是数据科学新手还是资深专家,都能在这里找到提升工...

gitblog_00359的博客 923

每周荐书:SQL优化、深度学习、数据科学家(评论送书)

每周荐书:SQL优化、深度学习、数据科学家(评论送书) 老规矩,感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 冲向改变 帝炎魔 《Swift进阶》   刘望舒 贾文静 《Java多线程编程实战指南(核心篇)》   当年的春天 llld5553 《React前端技术与工程实践》   请以上六位用户私信给小编快递地址,我尽快给各位发送奖品。

博文视点(北京)官方博客 1万+

Python并发简介

什么是并发? 简而言之,并发是指同时发生两个或多个事件。 并发是一种自然现象,因为许多事件在任何给定的时间同时发生。就编程而言,并发是两个任务在执行过程中重叠的时候。 通过并发编程,我们的应用程序和软件系统的性能可以得到提高,因为我们可以同时处理请求,而不是等待前一个完成再处理下一个。 高级并发基元 最近,由于引入了高级并发基元,程序员正在改进并发解决方案。改进了编程语言的并发性 Google的G...

Allen_by的博客 652

我想用python做金融,那你知道下面几点吗

Python程序员在银行和对冲基金中的需求旺盛。幸运的是,这种语言很容易学习 - 它经常被英国小学用来当做教授编程的基础知识。但是,在您第一次遇到Python之前,您应该了解一些事项 - 特别是如果您想在财务环境中使用它。 Python 3还是Python 2? 当新版本的语言出现时,它们通...

chuyinghuang8396的博客 744

如果想成为数据科学家,请学习这3种语言

随着大数据的应用与发展,各行业对具有数据科学技能的开发人员的需求持续增长。而希望成为数据科学家的技术人员需要学习如何融入这个领域的职业生涯。 寻求扩大在技术领域的技能?据技术招聘网站Indeed Prime主管Shu Wu介绍,目前对拥有数据科学技能的开发人员的需求目前“非常强劲”,过去四年来,数据科学家的职位需求“大幅增长”。 Shu Wu说:“数据科...

weixin_34349320的博客 106

python 多线程伪_26个你不知道的Python技巧,很难找到

Python是目前世界上最流行的编程语言之一。因为:1.它容易学习2.它用途超广3.它有非常多的开源支持(大量的模块和库)不好意思,优达菌又啰嗦了。本文作者 Peter Gleeson 是一名数据科学家,日常工作几乎离不开python。一路走来,他积累了不少有用的技巧和tips,现在优达菌就将这些技巧分享给大家。这些技巧将根据其首字母按A-Z的顺序进行展示。all or anyPython之所以成...

weixin_39581972的博客 98

你与数据科学家只差这26条python技巧

戳蓝字“优快云云计算”关注我们哦!作者 | Peter Gleeson来源 | Python数据科学编译 | wLsqPython是目前世界上最流行的编程语言之一。因为...

优快云业界要闻 287

每周荐书 SQL优化 深度学习 数据科学家 评论送书

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!                每周荐书:SQL优化、

akdjhf的博客 282
上一篇: Python的根号100个小知识 | 短小精悍
下一篇: Python2.x与3​​.x版本区别
python之光
博客等级 码龄7年 114粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值