您当前的位置:首页 > 时尚 > 内容

阻塞队列和非阻塞队列区别?

一、阻塞队列和非阻塞队列区别?

区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。

试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列.

1.ArrayDeque, (数组双端队列)

2.PriorityQueue, (优先级队列)

3.ConcurrentLinkedQueue, (基于链表的并发队列)

4.DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口)

5.ArrayBlockingQueue, (基于数组的并发阻塞队列)

6.LinkedBlockingQueue, (基于链表的FIFO阻塞队列)

7.LinkedBlockingDeque, (基于链表的FIFO双端阻塞队列)

8.PriorityBlockingQueue, (带优先级的无界阻塞队列)

9.SynchronousQueue (并发同步阻塞队列)

阻塞队列和生产者-消费者模式

阻塞队列(Blocking queue)提供了可阻塞的put和take方法,它们与可定时的offer和poll是等价的。如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。

Queue的长度可以有限,也可以无限;无限的Queue永远不会充满,所以它的put方法永远不会阻塞。

阻塞队列支持生产者-消费者设计模式。一个生产者-消费者设计分离了“生产产品”和“消费产品”。该模式不会发现一个工作便立即处理,而是把工作置于一个任务(“to do”)清单中,以备后期处理。

生产者-消费者模式简化了开发,因为它解除了生产者和消费者之间相互依赖的代码。生产者和消费者以不同的或者变化的速度生产和消费数据,生产者-消费者模式将这些活动解耦,因而简化了工作负荷的管理。

生产者-消费者设计是围绕阻塞队列展开的,生产者把数据放入队列,并使数据可用,当消费者为适当的行为做准备时会从队列中获取数据。生产者不需要知道消费者的省份或者数量,甚至根本没有消费者—它们只负责把数据放入队列。

类似地,消费者也不需要知道生产者是谁,以及是谁给它们安排的工作。BlockingQueue可以使用任意数量的生产者和消费者,从而简化了生产者-消费者设计的实现。最常见的生产者-消费者设计是将线程池与工作队列相结合。

阻塞队列简化了消费者的编码,因为take会保持阻塞直到可用数据出现。如果生产者不能足够快地产生工作,让消费者忙碌起来,那么消费者只能一直等待,直到有工作可做。同时,put方法的阻塞特性也大大地简化了生产者的编码;如果使用一个有界队列,那么当队列充满的时候,生产者就会阻塞,暂不能生成更多的工作,从而给消费者时间来赶进进度。

有界队列是强大的资源管理工具,用来建立可靠的应用程序:它们遏制那些可以产生过多工作量、具有威胁的活动,从而让你的程序在面对超负荷工作时更加健壮。

虽然生产者-消费者模式可以把生产者和消费者的代码相互解耦合,但是它们的行为还是间接地通过共享队列耦合在一起了

类库中包含一些BlockingQueue的实现,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO队列,与 LinkedList和ArrayList相似,但是却拥有比同步List更好的并发性能。PriorityBlockingQueue是一个按优先级顺序排序的队列,当你不希望按照FIFO的属性处理元素时,这个PriorityBolckingQueue是非常有用的。正如其他排序的容器一样,PriorityBlockingQueue可以比较元素本身的自然顺序(如果它们实现了Comparable),也可以使用一个 Comparator进行排序。

最后一个BlockingQueue的实现是SynchronousQueue,它根本上不是一个真正的队列,因为它不会为队列元素维护任何存储空间。不过,它维护一个排队的线程清单,这些线程等待把元素加入(enqueue)队列或者移出(dequeue)队列。因为SynchronousQueue没有存储能力,所以除非另一个线程已经准备好参与移交工作,否则put和take会一直阻止。SynchronousQueue这类队列只有在消费者充足的时候比较合适,它们总能为下一个任务作好准备。

非阻塞算法

基于锁的算法会带来一些活跃度失败的风险。如果线程在持有锁的时候因为阻塞I/O,页面错误,或其他原因发生延迟,很可能所有的线程都不能前进了。

一个线程的失败或挂起不应该影响其他线程的失败或挂起,这样的算法成为非阻塞(nonblocking)算法;如果算法的每一个步骤中都有一些线程能够继续执行,那么这样的算法称为锁自由(lock-free)算法。

在线程间使用CAS进行协调,这样的算法如果能构建正确的话,它既是非阻塞的,又是锁自由的。

非竞争的CAS总是能够成功,如果多个线程以一个CAS竞争,总会有一个胜出并前进。非阻塞算法堆死锁和优先级倒置有“免疫性”(但它们可能会出现饥饿和活锁,因为它们允许重进入)。

非阻塞算法通过使用低层次的并发原语,比如比较交换,取代了锁。原子变量类向用户提供了这些底层级原语,也能够当做“更佳的volatile变量”使用,同时提供了整数类和对象引用的原子化更新操作。

二、深入理解阻塞和非阻塞赋值的区别?

阻塞与非阻塞赋值的语言结构是Verilog语言中最难理解的概念之一。 有这样的两个要点:

(1)在描述组合逻辑的always块中用阻塞赋值,则综合成组合逻辑的电路结构;

(2)在描述时序逻辑的always块中用非阻塞赋值,则综合成时序逻辑的电路结构。

这样做的原因是: 这是因为要使综合前仿真和综合后仿真一致的缘故。 为了更好地理解上述要点,我们需要对Verilog语言中的阻塞赋值和非阻塞赋值的功能和执行时间上的差别有深入的理解。

我们定义下面的两个关键字:

RHS——方程式右手方向的表达式或变量可分别缩写成 RHS表达式或RHS变量;LHS ——方程式左手方向的表达式或变量可分别缩写成LHS 表达式或LHS变量。

IEEE Verilog标准定义了有些语句有确定的执行时间,有些语句没有确定的执行时间。

若有两条或两条以上的语句准备在同一时间执行,但由于语句的排列顺序不同,却产生了不同的输出结果。

这就是造成Verilog模块冒险和竞争的原因。

为了避免产生竞争,理解阻塞和非阻塞赋值在执行时间上的差别是至关重要的。 1、阻塞赋值 阻塞赋值用等号(=)表示。为什么称这种赋值为阻塞赋值呢?因为在赋值时先计算RHS部分的值,这是赋值语句不允许任何别的Verilog语言的干扰,直到现行的赋值完成时刻,即把RHS赋值给LHS的时刻,它才允许别的赋值语句的执行。

一般可综合的赋值操作在RHS不能设定延时(即使是0延时也不允许)。

从理论上讲,它与后面的赋值语句只有概念上的先后,而无实质的延迟。

若在RHS上加延迟,则在延迟时间会阻止赋值语句的执行,延迟后才进行赋值,这种赋值语句是不可综合的,在需要综合的模块设计中不可使用这种风格的代码。

所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上是在前一句赋值语句结束之后再开始赋值的。 2、非阻塞赋值 非阻塞赋值用小于等于号(<=)表示。为什么称这种赋值为非阻塞赋值呢?因为在赋值开始时计算RHS表达式,赋值操作时刻结束时更新LHS。在计算非阻塞赋值的RHS表达式和更新LHS期间,其他的Verilog语句,包括其他的非阻塞赋值语句都可能计算RHS表达式和更新LHS。

非阻塞赋值允许其他的Verilog语句同时进行操作。非阻塞赋值可以看作两个步骤的过程:

(1)在赋值开始时,计算非阻塞赋值RHS表达式;

(2)在赋值结束时,更新非阻塞赋值LHS表达式。

非阻塞赋值操作只能用于对寄存器类型变量进行赋值,因此只能用在“initial”块和“always”块等过程块中,而非阻塞赋值不允许用于连续赋值。

三、网络编程中阻塞和非阻塞socket的区别?

阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket.如果在队列中没有请示将会出现什么情况呢?那个方法将会等待一个的到来.这个行为叫阻塞.accept()方法将会阻塞服务器线程直到一个呼叫到来.当5个连接处理完闭之后,服务器退出.任何的在队列中的呼叫将会被取消.

非阻塞:非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的

四、socket中阻塞与非阻塞如何理解?

这个问题涉及三方面,一个是阻塞本身的定义,一个是阻塞现象,一个是阻塞模式设定 阻塞,就是阻挡,禁止做某工作 当系统出现阻塞现象时, 如果设置了阻塞模式,则当前程序会等待阻塞现象消失,然后继续做事情 如果设置了非阻塞模式,则,当前程序会马上返回相应的错误,停止做事情以上只是白话描述,细节内容还是要多读书去理解

五、怎么在非阻塞模式下调用阻塞recv?

应该是RECV()返回的错误吧,多调用几次直到收到数据为止即可原因是因为你用非阻塞调用RECV如果没数据就直接返回了最好使用事件模式啦,就不用不停调用RECV了

六、php非阻塞调用

随着互联网的发展和应用程序的日益复杂,高效处理并发请求的能力变得越来越重要。PHP作为一门流行的编程语言,也需要提供高效的非阻塞调用能力,以应对并发请求的挑战。

PHP非阻塞调用的概述

PHP非阻塞调用是指在处理某个操作时,不会等待该操作的完成,而是继续执行后续的代码。这种调用方式能够提高应用程序的并发处理能力,使应用能够更好地响应大量的并发请求。

在传统的PHP编程模型中,对于某些耗时较长的操作(如网络请求、数据库查询等),会阻塞当前的线程,导致整个应用程序的性能下降。而非阻塞调用则通过异步执行的方式,避免了线程的阻塞,从而提高了应用程序的性能。

实现PHP非阻塞调用的方式

要实现PHP的非阻塞调用,我们可以借助一些技术手段,如多进程、多线程、事件驱动等。下面介绍几种常见的实现方式。

多进程

多进程是一种比较常用的实现非阻塞调用的方式。通过创建多个子进程,在每个子进程中执行不同的操作,可以同时处理多个任务,从而提高应用程序的并发处理能力。

在PHP中,可以使用fork函数来创建子进程。每个子进程可以独立执行一段代码,并在执行完成后通过进程间通信的方式将结果返回给父进程。

多线程

多线程是另一种常见的实现非阻塞调用的方式。通过创建多个线程,在每个线程中执行不同的操作,可以同时处理多个任务,提高应用程序的并发处理能力。

在PHP中,可以使用多线程扩展(如pthread或pcntl)来实现多线程。每个线程可以独立执行一段代码,并在执行完成后将结果返回给主线程。

事件驱动

事件驱动是一种相对高效的实现非阻塞调用的方式。通过将任务注册到事件循环中,在该任务完成时触发对应的回调函数,从而实现非阻塞调用。

在PHP中,可以使用一些事件驱动框架(如Swoole、ReactPHP)来实现事件驱动编程。这些框架提供了底层的事件循环机制,使得我们可以方便地实现非阻塞调用。

PHP非阻塞调用的优势与应用

PHP非阻塞调用有许多优势,适用于各种场景。

高并发请求处理

PHP非阻塞调用能够提高应用程序的并发处理能力,使其能够同时处理大量的请求。这在一些高并发的场景下非常有用,例如电商网站的秒杀活动、社交媒体的热点话题等。

通过使用非阻塞调用,应用程序可以快速地响应大量的并发请求,避免因为请求堆积导致的性能下降。

资源利用率提升

传统的PHP编程模型中,每个请求都需要占用一个线程来处理,线程的创建和销毁会消耗大量的资源。而非阻塞调用可以减少线程的数量,从而提高资源的利用率。

通过使用非阻塞调用,应用程序可以同时处理多个请求,而不需要为每个请求创建一个线程,可以充分利用系统的资源。

提高用户体验

非阻塞调用能够快速地处理请求,并在后台执行相关任务,而不会阻塞用户的操作。这可以提高用户的体验,使得用户能够更快地获取到结果。

例如,在一个Web应用中,用户提交了一个表单,如果使用非阻塞调用来处理表单的提交,用户可以立即得到一个反馈,而不需要等待服务器的响应。

结论

PHP非阻塞调用是提高应用程序并发处理能力的重要手段。通过采用多进程、多线程、事件驱动等方式,可以实现PHP的非阻塞调用。

非阻塞调用可以提高应用程序的性能、资源利用率,同时提升用户的体验。在面对高并发的场景时,非阻塞调用是一个值得考虑的解决方案。

七、php curl 非阻塞

PHP Curl 非阻塞: 在网络请求中,非阻塞(又称异步)是指不必等待当前操作完成才能进行下一步操作的一种处理方式。对于使用 PHP 编程语言中的 Curl 库进行网络请求的开发者来说,了解如何使用非阻塞方式发起 Curl 请求是提升性能和效率的关键。

Curl 介绍

Curl 是一个利用 URL 语法规定在命令行下工作的文件传输工具,同时也是一个库,支持许多协议,包括 HTTP、HTTPS、FTP 等。在 PHP 中,Curl 扩展提供了请求 URL 并获取数据的功能,是进行网络通信的重要工具。

PHP Curl 阻塞与非阻塞

默认情况下,PHP 中的 Curl 请求是阻塞的,即在发送网络请求后,脚本会一直等待服务器的响应,直到接收到完整的数据后才继续执行后续代码。而非阻塞方式发起 Curl 请求则允许脚本在等待响应的同时继续执行后续代码,从而提高了整体性能和响应速度。

实现非阻塞 Curl

要实现 PHP Curl 的非阻塞请求,最常见的方式是通过使用多线程或异步的方法。下面简要介绍几种实现非阻塞 Curl 请求的方法:

使用 Curl Multi:Curl 提供了一个名为 Curl Multi 的多接口处理机制,可以同时处理多个 Curl 请求,允许并行地处理多个请求,从而实现非阻塞效果。 使用异步库:借助异步库或框架,如 Swoole、ReactPHP 等,可以更方便地实现 PHP Curl 的非阻塞请求,大大简化了异步编程复杂性。

示例代码

下面是一个简单的示例代码,演示如何使用 Curl Multi 实现 PHP Curl 非阻塞请求:

<?php // 初始化 Curl Multi $multiHandle = curl_multi_init(); // 初始化 Curl $ch1 = curl_init('e.com/endpoint1'); $ch2 = curl_init('e.com/endpoint2'); // 将 Curl 资源添加到 Curl Multi curl_multi_add_handle($multiHandle, $ch1); curl_multi_add_handle($multiHandle, $ch2); // 执行 Curl Multi $running = null; do { curl_multi_exec($multiHandle, $running); } while ($running > 0); // 关闭 Curl curl_multi_remove_handle($multiHandle, $ch1); curl_multi_remove_handle($multiHandle, $ch2); curl_multi_close($multiHandle); ?>

结语

通过了解和掌握 PHP Curl 非阻塞请求的实现方式,开发者可以更好地优化网络请求的性能,提高代码的可扩展性和稳定性。合理地运用非阻塞方式,可以让 PHP 应用更高效地处理网络通信,提升用户体验,是优化 PHP 项目的重要手段之一。

八、VC中使用API编写的socket程序中如何设置阻塞和非阻塞accept?

阻塞就是说 accept() 执行时会一直停留在此调用中,直到返回正确的 connfd 前,不会执行 accept() 之后的代码。非阻塞就是说 accept() 执行时会立即返回结果,成功就返回正确的 connfd ,失败就返回相应错误码。 相应的代码就要不停的 accept() ,并处理成功和失败的情况,但是因为 accept() 能快速返回结果,程序就很好的立即这个间隙,做此其他更有意义的事件。上面描述的过程并不完全准确,具体原理建议阅读

UNIX网络编程 (豆瓣)

九、与非逻辑门的逻辑特性?

TTL与非门的特性参数:

1输出高电平U(OH):至少有一个输入端接低电平时的输出电平。电压传输特性的截止区的输出电压为3.6V,一般产品规定UOH≥2.4V即为合格。

2输出低电平U(OL):输入全为高电平时的输出电平。电压传输特性的饱和区的输出电压为0.3V。一般产品规定UOL<0.4V时即为合格。

3开门电平U(ON):是保证输出电平达到额定低电平(0.3V)时,所允许输入高电平的最低值,表示使与非门开通的最小输入电平。一般产品规定UON≤1.8V。

4关门电平U(OFF):是保证输出电平为额定高电平(2.7V左右)时,允许输入低电平的最大值,表示与非门关断所允许的最大输入电平。一般产品要求UOFF≥0.8V。

5扇入系数N(i):是指与非门的输入端数目。

6扇出系数N(O):是指与非门输出端连接同类门的个数。反映了与非门的带负载能力。

7平均传输延迟时间t(pd):平均延迟时间是衡量门电路速度的重要指标,指一个矩形波信号从与非门输入端到与非门输出端所延迟的时间。通常将从输入波上沿中点到输出波下沿中点的时间延迟称为导通延迟时间t(PHL),从输入波下沿中点到输出波上沿中点的时间延迟称为截止延迟时间t(PLH)。tpd为t(PLH)和t(PHL)的平均值,TTL门的t(pd)在3~40ns之间。

8平均功耗P:指在空载条件下工作时所消耗的电功率。

十、java非阻塞监听端口

在软件开发领域,Java非阻塞监听端口是一项重要的技术,特别适用于需要高性能和并发处理能力的应用程序。通过非阻塞机制,可以实现同时监听多个端口或者文件描述符,提高程序的效率和响应速度。

什么是非阻塞监听端口?

Java非阻塞监听端口是指在程序中使用非阻塞I/O模式来监听指定的端口,而不会因为某个I/O操作的阻塞而影响其他操作的进行。在传统的阻塞式I/O模式下,当一个操作被阻塞时,整个程序的执行就会被阻塞,无法响应其他请求。

而非阻塞I/O模式则可以让程序在等待某个操作完成的同时继续执行其他操作,提高了程序的并发处理能力和效率。

为什么使用非阻塞监听端口?

使用Java非阻塞监听端口可以带来多方面的好处。首先,通过非阻塞I/O可以同时监听多个端口,实现多路复用,提高了系统的性能和吞吐量。

其次,非阻塞监听端口可以避免因为某个I/O操作阻塞导致整个程序的停顿,提高了系统的稳定性和可靠性。

另外,非阻塞I/O模式可以减少线程的创建和上下文切换,降低了系统的资源消耗,适用于高并发场景下的应用程序。

如何实现Java非阻塞监听端口?

实现Java非阻塞监听端口可以借助Java NIO(New I/O)提供的相关类和方法。通过Selector、Channel和Buffer等组件,可以轻松实现非阻塞I/O操作。

首先,需要创建一个Selector对象,并将需要监听的Channel注册到Selector上。然后,在循环中不断调用Selector的select()方法,监听Channel上的事件并处理。

在事件发生时,可以通过Channel读取或写入数据,实现异步非阻塞的I/O操作。通过适当地使用Buffer来缓冲数据,可以提高数据的处理效率。

应用领域和案例

Java非阻塞监听端口广泛应用于网络编程、服务器开发、消息队列等需要高性能和并发处理的领域。

例如,在Web服务器开发中,可以使用非阻塞监听端口来实现高并发的HTTP请求处理,提升服务器的响应速度和吞吐量。

另外,在消息队列系统中,非阻塞监听端口可以帮助系统实现高效的消息传递和处理,提高系统的性能和稳定性。

总结

Java非阻塞监听端口是一项重要的技术,可以帮助程序实现高性能、高并发的I/O操作。通过使用非阻塞I/O模式,可以提高程序的效率、稳定性和可靠性,适用于各种需要快速响应和并发处理的应用场景。

在今后的软件开发中,更多地了解和掌握非阻塞监听端口技术,将有助于提升自身的技术水平和开发能力,为构建高性能的应用程序打下坚实的基础。


声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,谢谢。

上一篇: 请数模高手解释一下优化问题中的线性和非线性的概念

下一篇: 辩论赛与学校育人



猜你感兴趣

推荐阅读

网站内容来自网络,如有侵权请联系我们,立即删除! | 软文发布 | 粤ICP备2021106084号