AI

您将深入了解人工智能(AI)的核心技术与应用,包括机器学习、深度学习、自然语言处理、计算机视觉等热门领域。我们提供最新的AI教程、技术文章、行业案例与实践指南,帮助您掌握AI技术,提升编程与数据分析能力。无论您是AI初学者还是专业开发者,都可以在这里找到丰富的学习资源,助力您的职业发展与技术创新。关注我们的AI板块,了解AI最新趋势,抢占未来科技先机!

python并发与并行(一) ———— 用subprocess管理子进程

python并发与并行(一) ———— 用subprocess管理子进程

并发(concurrency)指计算机似乎能在同一时刻做许多件不同的事情。例如,在只配有一个CPU核心的计算机上面,操作系统可以迅速切换这个处理器所运行的程序,因此尽管同一时刻最多只有一个程序在运行,但这些程序能够交替地使用这个核心,从而造成一种假象,让人觉得它们好像真的在同时运行。 并行(parallelism)与并发的区别在于,它强调计算机确实能够在同一时刻做许多件不同的事情。例如,若计算机配有多个CPU核心,那么它就真的可以同时执行多个程序。每个CPU核心执行的都是自己的那个程序之中的指令,这些程序能够同时向前推进。 并行与并发之间的区别,关键在于能不能提速(speedup)。如果程序把总任务量分给两条独立的执行路径去同时处理,而且这样做确实能让总时间下降到原来的一半,那么这就是并行,此时的总速度是原来的两倍。反过来说,假如无法实现加速,那即便程序里有一千条独立的执行路径,也只能叫作并发,因为这些路径虽然看起来是在同时推进,但实际上却没有产生相应的提速效果。 用subprocess管理子进程 我们可以通过subprocess来执行命令行工具,因为shell脚本越写会越复杂

python并发与并行(三) ———— 利用Lock防止多个线程争用同一份数据

python并发与并行(三) ———— 利用Lock防止多个线程争用同一份数据

了解到全局解释器锁(GIL)的效果之后,许多Python新手可能觉得没必要继续在代码里使用互斥锁(mutual-exclusion lock,mutex)了。既然GIL让Python线程没办法平行地运行在多个CPU核心上,那是不是就意味着它同时还会自动保护程序里面的数据结构,让我们不需要再加锁了?在列表与字典等结构上面测试过之后,有些人可能真的以为是这样的。 其实并非如此。GIL起不到这样的保护作用。虽说同一时刻只能有一条Python线程在运行,但这条线程所操纵的数据结构还是有可能遭到破坏,因为它在执行完当前这条字节码指令之后,可能会被Python系统切换走,等它稍后切换回来继续执行下一条字节码指令时,当前的数据或许已经与实际值脱节了,因为中途切换进来的其他线程可能更新过这个值。所以,多个线程同时访问同一个对象是很危险的。每条线程在操作这份数据时,都有可能遭到其他线程打扰,因此数据之中的固定关系或许已经被别的线程破坏了,这会令程序陷入混乱状态。 我们用一个程序来模拟传感器采集数据,然后使用多线程来统计最终传感器采集到的值。 这个Python代码示例主要演示了多线程环境下的并发问题

python并发与并行(四) ———— 用queue来协调多个线程之间的工作进度

python

python并发与并行(四) ———— 用queue来协调多个线程之间的工作进度

Python程序如果要同时执行多项任务,而这些任务又分别针对同一种产品的不同环节,那么就有可能得在它们之间进行协调。比较有用的一种协调方式是把函数拼接成管道。 这样的管道与生产线比较像。它可以按先后顺序划分成几个阶段,每个阶段都由相应的函数负责。程序会把未经加工的原料放在生产线(也就是管道)的起点,而那些函数,则分别关注着自己所负责的这一段,只要有产品来到当前环节,它就对这件产品做出相应的加工处理。如果所有函数都不会再收到有待加工的产品,那么整条生产线就可以关停。这套方案,很适合应对与阻塞式I/O或子进程有关的需求,因为我们很容易就能在Python程序里,平行地开启多个线程来分别负责生产线中的某个环节。 例如,要构建这样一套系统,让它持续从数码相机里获取照片,然后调整照片尺寸,最后把调整好的照片添加到网络相册之中。如果用管道来实现,那么这个管道就有三个环节。第一个环节是,从数码相机里下载新图像;第二个环节是,调整这些图像的尺寸;第三个环节是,把尺寸已经调整好的图像上传到网络相册里面。 假如这三个环节所对应的download、resize与upload函数,如下面的示例程序所示。

python并发与并行(五.2) ———— 不要在每次fan-out时都新建一批Thread实例

python并发与并行(五.2) ———— 不要在每次fan-out时都新建一批Thread实例

想在Python里平行地做I/O,首先要考虑的工具当然是线程。但如果真用线程来表示fan-out模式中的执行路径,你就会发现,这样其实有很多问题。 我们用上一篇文章的conway game的实现来举例说明。 我们用线程来解决game_logic函数由于执行I/O而产生的延迟问题。首先,这些线程之间需要锁定功能对其进行协调,以确保它们所操纵的数据结构不会遭到破坏。下面创建Grid子类,并为它添加锁定功能,让多条线程能够正确地访问同一个实例。 下面创建Grid子类,并为它添加锁定功能,让多条线程能够正确地访问同一个实例。 from threading import Lock ALIVE = '*' EMPTY = '-' class Grid: def __init__(self, height, width): self.height = height self.width = width self.rows = [] for _ in range(self.

python并发与并行(八) ———— 用协程实现高并发的I/O

python并发与并行(八) ———— 用协程实现高并发的I/O

在前面几条里,我们以生命游戏为例,试着用各种方案解决I/O并行问题,这些方案在某些情况下确实可行,但如果同时需要执行的I/O任务有成千上万个,那么这些方案的效率就不太理想了 像这种在并发方面要求比较高的I/O需求,可以用Python的协程(coroutine)来解决。协程能够制造出一种效果,让我们觉得Python程序好像真的可以同时执行大量任务。这种效果需要使用async与await关键字来实现,它的基本原理与生成器(generator)类似,也就是不立刻给出所有的结果,而是等需要用到的时候再一项一项地获取 启动协程是有代价的,就是必须做一次函数调用。协程激活之后,只占用不到1KB内存,所以只要内存足够,协程稍微多一些也没关系。与线程类似,协程所要执行的任务也是用一个函数来表示的,在执行这个函数的过程中,协程可以从执行环境里面获取输入值,并把输出结果放到这个执行环境之中。协程与线程的区别在于,它不会把这个函数从头到尾执行完,而是每遇到一个await表达式,就暂停一次,下次继续执行的时候,它会先等待await所针对的那项awaitable操作有了结果(那项操作是用async函数表示的

python并发与并行(九) ———— 用asyncio改写通过线程实现的IO

python

python并发与并行(九) ———— 用asyncio改写通过线程实现的IO

知道了协程的好处之后,我们可能就想把现有项目之中的代码全都改用协程来写,于是有人就担心,这样修改起来,工作量会不会比较大呢?所幸Python已经将异步执行功能很好地集成到语言里面了,所以我们很容易就能把采用线程实现的阻塞式I/O操作转化为采用协程实现的异步I/O操作。 在这里我们要补充下线程和协程的区别,以及他们在执行阻塞式IO和异步IO上的区别。 在计算机编程中,I/O(输入/输出)操作通常涉及等待外部事件完成,如磁盘读写、网络通信等。线程和协程是两种不同的并发执行单元,它们处理阻塞式I/O和异步I/O的方式不同: 1. 线程(Thread): * 线程是操作系统层面的执行单元,拥有自己的栈和独立的执行路径。 * 当线程执行阻塞式I/O操作时,它会在操作完成之前被操作系统挂起,不会执行其他任务。这意味着在等待I/O操作完成期间,线程不能做其他工作,从而导致资源的浪费。 * 为了解决这个问题,可以使用多线程,其中一个线程等待I/O操作时,其他线程可以继续执行。但这增加了程序的复杂性,如需要同步和通信机制来避免竞态条件和死锁。 1. 协程(Coroutine)

python并发与并行(十) ———— 结合线程与协程,将代码顺利迁移到asyncio

python并发与并行(十) ———— 结合线程与协程,将代码顺利迁移到asyncio

在前一篇中,我们用asyncio模块把通过线程来执行阻塞式I/O的TCP服务器迁移到了协程方案上面。当时我们一下子就完成了迁移,而没有分成多个步骤,这对于大型的项目来说,并不常见。如果项目比较大,那通常需要一点一点地迁移,也就是要边改边测,确保迁移过去的这一部分代码的效果跟原来相同。 为了能够分步骤地迁移,必须让采用线程做阻塞式I/O的那些代码能够与采用协程做异步I/O的代码相互兼容。具体来说,这要求我们既能够在线程里面执行协程,又能够在协程里面启动线程并等待运行结果。好在asyncio模块已经内置了相关的机制,让线程与协程可以顺利地操作对方。 例如,现在要写一个程序,把许多份日志文件合并成一条输出流,以便我们调试程序。给定日志文件的句柄之后,我们得想办法判断有没有新数据到来,如果有,就返回下一行输入内容。为了实现这项功能,可以调用文件句柄的tell方法,并判断当前读取到的这个位置是否为文件中的最后一个位置。若是,就说明没有新数据,这时应该抛出异常。 class NoNewData(Exception): pass def readline(handle): o

python并发与并行(十一) ———— 让asyncio的事件循环保持畅通,以便进一步提升程序的响应能力

python并发与并行(十一) ———— 让asyncio的事件循环保持畅通,以便进一步提升程序的响应能力

前一篇blog说明了怎样把采用线程所实现的项目逐步迁移到asyncio方案上面。迁移后的run_tasks协程,可以将多份输入文件通过tail_async协程正确地合并成一份输出文件。 import asyncio # On Windows, a ProactorEventLoop can't be created within # threads because it tries to register signal handlers. This # is a work-around to always use the SelectorEventLoop policy # instead. See: https://bugs.python.org/issue33792 policy = asyncio.get_event_loop_policy() policy._loop_

python并发与并行(十二) ———— 考虑用concurrent.futures实现真正的并行计算

python

python并发与并行(十二) ———— 考虑用concurrent.futures实现真正的并行计算

有些Python程序写到一定阶段,性能就再也上不去了。即便优化了代码,程序的执行速度可能还是达不到要求。考虑到现在的计算机所装配的CPU核心数量越来越多,所以我们很自然地就想到用并行方式来解决这个问题。那么接下来就必须思考,如何将代码所要执行的计算任务划分成多个独立的部分并在各自的核心上面平行地运行。 Python的全局解释器锁(global interpreter lock,GIL)导致我们没办法用线程来实现真正的并行,所以先把这种方案排除掉。另一种常见的方案,是把那些对性能要求比较高的(performance-critical)代码用C语言重写成扩展模块。C语言比Python更接近底层硬件,因此运行速度要比Python快,这样的话,有些任务可能根本就不需要做并行,而是单单用C语言重写一遍就好。另外,C扩展还可以启动原生线程(native thread),这种线程不受Python解释器制约,也不必考虑GIL的问题,它们能够平行地运行,从而发挥出多核CPU的优势。Python里面针对C扩展而设计的那些API,有详细的文档可以参考,所以这是个很好的备选方案。大家在开发扩展模块的时候,还

TensorFlow版BERT源码详解之self-attention

TensorFlow版BERT源码详解之self-attention

self-attetion是BERT中的最为核心的内容之一,虽然TensorFlow版的BERT中的self-attention的原理和论文中是一致的,但是实现代码却有所出入。为了帮助新手快速理解这部分内容,所以通过该篇博客逐行解释具体代码。 文章目录 * * * 1. 函数参数 def attention_layer(from_tensor, to_tensor, attention_mask=None, num_attention_heads=1, size_per_head=512, query_act=None, key_act=None, value_act=None, attention_probs_dropout_prob=0.0,

Linux 下超级终端 minicom 使用总结

Linux 下超级终端 minicom 使用总结

参照下面这篇blog: http://hi.baidu.com/zengzhaonong/blog/item/8427c633c835de40ac4b5f47.html 1. 安装配置minicom -------------------------------------------------- # lsmod | grep usbserial(如果直接使用串口线,而没有用到USB转串口设备,此步可以跳过)    如果有usbserial,说明系统支持USB转串口。 安装minicom (Fedora自带有minicom,此步可以跳过)    apt-get install minicom    apt-get install lrzsz 配置minicom    #sudo  minicom -s   ===> 其实就是生成/etc/minicom/minirc.dfl    Serial port setup[Enter]     +-------------------------------------------------------------+