Questions tagged «concurrency»

并发是其中多个进程同时执行的系统的属性。

7
为什么要知道并发编程?
并发编程对我来说相当困难:即使看一张基本幻灯片对我来说也充满挑战。看来太抽象了。 很好地了解并发编程概念有什么好处?它对定期进行顺序编程有帮助吗?我知道了解我们的程序如何工作很满意,但是还有什么呢?

2
如何使通用结构更有效率?
“通用构造”是顺序对象的包装器类,可使它线性化(并发对象的强一致性条件)。例如,这是来自Java [1]的一种经过修改的免等待构造,它假定存在一个满足接口的等待空闲队列WFQ(仅需要线程之间的一次性共识)并假定一个Sequential接口: public interface WFQ<T> // "FIFO" iteration { int enqueue(T t); // returns the sequence number of t Iterable<T> iterateUntil(int max); // iterates until sequence max } public interface Sequential { // Apply an invocation (method + arguments) // and get a response (return value + state) Response apply(Invocation …

5
学习并发和多线程应用程序的最佳资源是什么?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 4年前关闭。 已锁定。这个问题目前不接受新的答案或互动。了解更多。 我意识到我在多线程应用程序和并发编程方面存在巨大的知识鸿沟。过去,我已经介绍了一些基础知识,但是大部分内容似乎都已遗忘,这绝对是我想要且需要了解的领域。 学习构建并发应用程序的最佳资源是什么?我是一个非常务实的人,因此,如果所说的书包含一些具体的例子会更好,但是我愿意提出建议。我个人更喜欢使用伪代码或C ++,并且最好还是偏向游戏开发,但不是必需的。

1
消费者/生产者与观察者/可观察者之间的差异
我正在设计一个包含三个部分的应用程序: 监视某些事件(文件创建,外部请求等)发生的单个线程 N个工作线程通过处理它们来响应这些事件(每个工作进程处理并消耗一个事件,并且处理可能需要花费可变的时间) 一个控制器,用于管理那些线程并执行错误处理(线程重新启动,结果记录) 尽管这是非常基本的,并且不难实现,但我想知道这样做的“正确”方法是什么(在Java的这种具体情况下,但也希望有更高的抽象答案)。我想到两种策略: 观察者/可观察者:监视线程由控制器观察。在发生事件的情况下,然后会通知控制器,并可以将新任务分配给可重用的缓存线程池中的空闲线程(如果所有线程当前都忙,请等待并将任务缓存在FIFO队列中)。工作线程实现Callable并返回结果(或布尔值)成功或返回错误,在这种情况下,控制器可以决定要执行的操作(取决于发生的错误的性质)。 生产者/消费者:监视线程与控制器(事件队列)共享一个BlockingQueue,并且控制器与所有工作器(任务队列和结果队列)共享两个。在发生事件的情况下,监视线程将任务对象放入事件队列中。控制器从事件队列中获取新任务,对其进行审阅并将其放入任务队列中。每个工作人员都在等待新任务,并从任务队列中获取/使用它们(先到先服务,由队列本身进行管理),然后将结果或错误放回到结果队列中。最后,控制器可以从结果队列中检索结果,并在出现错误的情况下采取相应的步骤。 两种方法的最终结果是相似的,但是它们都有细微的差别: 使用观察者,线程的控制是直接的,每个任务都归属于特定的新生成的工作程序。创建线程的开销可能更高,但是由于缓存了线程池,因此开销并不大。另一方面,“观察者”模式被简化为单个“观察者”模式,而不是多个观察者模式,这与其设计的目的不完全相同。 队列策略似乎更容易扩展,例如,添加多个生产者而不是一个生产者很简单,不需要任何更改。不利之处在于,即使根本不做任何工作,所有线程也将无限期运行,并且错误/结果处理看起来不像第一个解决方案那样优雅。 在这种情况下最合适的方法是什么?为什么?我发现很难在线找到该问题的答案,因为大多数示例仅处理明确的案例,例如用“观察者”案例更新许多具有新值的窗口或与多个消费者和生产者进行处理。任何输入,不胜感激。

3
并行性意味着并发,但不是相反吗?
我经常读到并行性和并发性是不同的东西。答题者/评论者经常会写到他们是两个完全不同的事物。但是我认为它们是相关的,但我想对此进行一些说明。 例如,如果我在多核CPU上并设法将计算分成x个较小的计算(例如使用fork / join),每个计算均在其自己的线程中运行,则我将拥有一个同时进行并行计算的程序(因为大概在任何时候,几个线程都将在多个内核上运行)并且是并发的吗? 虽然如果我只是简单地使用Java,并处理事件调度线程上的UI事件和重绘,再运行我创建的唯一线程,那么我将拥有一个并发程序(EDT + GC线程+我的主线程)等),但不是并行的。 我想知道我是否正确,并行性(在“单核但多核”系统上)是否总是暗示并发? 另外,是否在多核CPU上运行多线程程序,但是不同线程在进行完全不同的计算的情况下是否考虑使用“并行性”?

1
通用C ++包装器能否实现Rust的所有权模型?
浏览有关Rust的并发安全性的这篇文章: http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html 我想知道在C ++ 11(或更新版本)中可以实现多少这些想法。特别是,我可以创建一个所有者类,将所有权转移到可能传递给它的任何方法吗?似乎C ++有太多传递变量的方法,这是不可能的,但是也许我可以对类或模板施加一些限制,以确保每次方法传递都执行某些模板代码?

2
如果事务永远不会跨越多个对象,那么每个对象的乐观并发性是否意味着可串行化?
给定一个提供以下功能的系统: 每个对象的乐观并发控制/版本控制(使用CAS-Check-and-Set) 不需要跨多个对象的事务。 快照隔离 该系统是否可序列化? 从快照隔离 在写偏斜异常中,两个事务(T1和T2)同时读取重叠的数据集(例如值V1和V2),并发进行不相交的更新(例如T1更新V1,T2更新V2),最后并发提交,都没有看到对方执行的更新。如果系统可序列化,那么这种异常将是不可能的,因为T1或T2都必须“首先”发生,而另一个则可见。相反,快照隔离允许写偏斜异常。 举一个具体的例子,假设V1和V2是一个人Phil持有的两个天平。银行将允许V1或V2出现赤字,前提是两者中所持的总和决不为负(即V1 + V2≥0)。目前两个余额均为$ 100。Phil同时发起了两个交易,T1从V1提取200美元,T2从V2提取200美元。 基于此,似乎存在写偏斜的可能性是保证快照隔离不可序列化的系统的唯一原因。 但是,在不允许事务跨越多个对象的系统中(在上面的示例V1和V2中),似乎不可能发生写偏斜。 因此,上述系统是可序列化的。它是否正确?

2
我对演员模型的描述正确吗?
据我了解,参与者模型就像对象模型一样,但是有一些区别: 每个对象都产生它自己的单独线程,即使有成千上万个对象,也不是问题。 参与者不是通过调用函数和获取返回值来进行交互,而是通过发送和接收消息来进行交互。 如果您不违反该模型,则您的应用将充分利用并发功能,而不会出现竞争状况的风险。 在OO中可以执行的所有操作都可以使用actor来完成,但更好的是,问题在于最近几年我们编写的所有内容都是基于OO的-但即将进行过渡。 因此,举例来说,假设我必须定义3d向量类/角色,创建两个实例,并对它们调用求和运算。 面向对象: class V3d { constructor V3d(x,y,z) //bla float x,y,z; function sum(V3d b) { return V3d(x+b.x,y+b.y,z+b.z); } } //using: mySum = V3d(1,2,3).sum(V3d(3,2,1)) //creates 2 instances, sum, returns instantly drawPoint(mySum) //uses the result 演员模型: actor V3d { constructor V3d(x,y,z) //bla float x,y,z; loop { receive 'sum',b:V3d …

5
为什么隐式并行/并发没有得到更广泛的应用?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 隐式并行性^可以减轻许多程序员的负担,并将其放置在计算机上。那么...为什么它现在不普及? ^隐式并行性是使计算机能够一次弄清楚自己如何做一件事,而不是程序员需要使用线程等来完成这项工作。


1
哪些中间表示可用于推理并发?
我试图更好地理解编译器能够代表程序员对并发做出明智选择的要求。我意识到例如这个问题有很多困难的方面: 确保没有比赛条件 确保要同时运行的代码不会产生影响代码语义的副作用 给定代码中可用的并行度,确定是否有必要分散线程的开销 我的理解是,现代编译器中使用的两个主要中间表示形式是面向过程和面向对象语言的静态单一分配,以及面向功能语言的延续传递样式。使用这些中间形式似乎很难对上面列出的任何问题进行推理。即使是理论上应该在自动并行化方面机会最大的语言(诸如Haskell这样的纯功能语言,也没有副作用)在这方面也取得了有限的进展。 所以我的问题是,实际上使用了哪些中间表示来尝试解决该问题?我还不知道还有其他一些学术研究中使用的表示形式更适合此任务吗?这个问题是否是编译器前端必须从根本上通过在编译到达中间表示之前操纵抽象语法树来解决的问题?

2
免费午餐结束了吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 在2005 年发表的著名的《免费午餐结束》中,Herb Sutter预测了并发编程革命与面向对象革命一样大。这场革命真的发生在2005年-2013年吗? 本文的重点: 处理器制造商已经没有足够的空间来使用大多数传统方法来提高CPU性能。他们没有提高时钟速度,反而转向超线程和多核体系结构。 如果应用程序要充分利用CPU吞吐量的增长,它们将越来越需要并发。 “哦,性能无关紧要,计算机只会保持更快的速度”这句话是错误的。 效率和性能优化将变得越来越重要,而不是更少。那些已经可以进行大量优化的语言将会找到新的生命。那些不需要的人将需要找到竞争的方法,变得更加高效和乐观。预计对面向性能的语言和系统的需求将长期增长。 编程语言和系统将越来越被迫处理并发问题。我们迫切需要比今天的语言提供更高级别的并发编程模型。

2
这些关于Java并发性的高级/不公平面试问题吗?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 这是我最近问过的受访者的一些问题,这些受访者说他们知道Java并发性: 解释“内存可见性”的危害-JVM可以对不受监视器保护且未声明的变量重新排序某些操作的方式volatile,以使一个线程可能看不到另一个线程所做的更改。通常,我通过显示存在此危害的代码来问这个问题(例如NoVisibility,Goetz等人的“ Java Concurrency in Practice”中的清单3.1中的示例),并询问出了什么问题。 说明不仅volatile影响声明的实际变量volatile,而且还影响线程在更改volatile变量之前对变量所做的任何更改。 为什么用volatile代替synchronized? 使用wait()和实现条件变量notifyAll()。说明为什么要使用notifyAll()。说明为什么要使用while循环测试条件变量。 我的问题是-这些是适当的还是太高级了,无法问一个知道Java并发的人? 而当我们讨论它时,您是否认为应该期望从事Java并发工作的人员对Java垃圾回收的了解高于平均水平?

2
如果其中一项失败,您如何设计更新多个微服务的软件?
我是否可以使用设计模式或实践来帮助出现故障或停机的服务,而其他服务却保持稳定? 如果我有三个微服务,其中两个很好,又在POST中间死了怎么办?有两个将获得POST,而一个则不会。我认为我无法进行交易,因为我正在将请求发送给服务。 我该如何设计?我不想在各种数据库中孤立数据。

1
Erlang在哪些方面可以防止并发编程中的竞争条件?
阅读有关Erlang的并发信息,使我想起了Akka并发工具包。两者都为您提供了预防或限制比赛条件的工具。但是您可以使用Akka工具包将可变数据的链接发送到其他进程,这仍然是不安全的。我认为Akka是一种有用的工具,但它不能防止对对象和数据的乱序访问,从而导致竞争情况,死锁和/或饥饿。它并不能阻止您以Java或C#保护您免于编写可以在C ++中编写的大多数类型的内存泄漏的方式编写不安全的代码(您仍然可以通过欺骗垃圾收集器来在Java中创建内存泄漏,但是这种情况较少而不是必须记住释放分配的每个字节)。 Erlang是否在并发编程中保证一定程度的正确性,性能和鲁棒性?我认为操作系统在访问系统资源时会提供保护(假设驱动程序编写者的工作做得很好)。ACID数据库为读取和更新提供保护。因此,这似乎是一个可解决的问题。还是通用安全解决方案会消除并发性带来的性能提升?其他语言或工具包是否提供Erlang提供(或不提供)的并发安全性? 这是@Malfist对@ user1249的回答的评论的后续问题,即哪种编程语言生成最少的难以发现的错误?。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.