Questions tagged «multithreading»

与多线程相关的问题,包括技术,结构和安全性问题。

1
绘图线程交互
我想以UML(类似)表示法绘制(笔和铅笔)线程交互。我并不坚持使用UML,任何对读者来说显而易见的事情都应该做。 我从顺序图开始,但我不认为这是实现此目的的最佳方法。一直以来,屏幕外都会有“行动发起人”,这有点违反了SSD的想法。我继承了一个中等大小的代码库,每个线程都有一个状态机,大约有9-10个线程,我试图弄清楚它是如何工作的。 我应该如何可视化线程交互?

8
您从一个因多线程不良而几乎/实际上失败的项目中学到了什么?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 6年前关闭。 您从一个因多线程不良而几乎/实际上失败的项目中学到了什么? 有时,框架会采用某种线程模型,使事情难以正确处理一个数量级。 对于我来说,我还没有从上一次失败中恢复过来,我觉得最好不要在该框架中处理与多线程有关的任何事情。 我发现我擅长处理多线程问题,这些问题具有简单的fork / join,并且数据仅在一个方向上传播(而信号可以在圆形方向上传播)。 我无法处理GUI,其中某些工作只能在严格序列化的线程(“主线程”)上完成,而其他工作只能在除主线程(“工作线程”)之外的任何线程上完成,并且数据和消息必须在N个组件之间完全传播(完整连接的图表)。 在我将该项目移交给另一个项目时,到处都有僵局问题。我听说2-3个月后,其他几位开发人员设法解决了所有僵局问题,以至于可以将其交付给客户。我从未设法找出我所缺少的知识。 关于项目的一些事情:消息ID(描述事件含义的整数值,可以将其发送到另一个对象的消息队列中,而与线程无关,而已)达到数千。唯一字符串(用户消息)也有大约一千。 添加 我从另一个团队得到的最好的类比(与我的过去或现在的项目无关)是“将数据放入数据库”。(“数据库”指的是集中化和原子更新。)在分为多个视图且全部在同一“主线程”上运行且所有非GUI繁重工作都在单个工作线程中完成的GUI中,应用程序的数据应可以将其存储在一个像数据库一样的单一文件中,并让“数据库”处理涉及非平凡数据依赖项的所有“原子更新”。GUI的所有其他部分仅处理屏幕绘图,而没有其他内容。UI部分可能会缓存内容,并且如果设计正确,用户将不会注意到它是否过时了不到一秒钟。此“数据库”也称为“文档” 在文档视图体系结构中。不幸的是-不,我的应用程序实际上将所有数据存储在“视图”中。我不知道为什么会这样。 会员贡献者: (贡献者不需要使用真实/个人示例。如果您自己认为可信的轶事示例,也欢迎他们提供经验教训。)

2
有多少个使用线程?
当我在台式机/笔记本电脑上(重新)构建大型系统时,我告诉我make使用多个线程来加快编译速度,如下所示: $ make -j$[ $K * $C ] $C应该在哪里指示机器拥有的内核数量(我们可以假设它是一位数字),而根据我的心情,$K我从2到有所不同4。 因此,例如,我可能会说make -j12我是否有4个核心,这表示make要使用多达12个线程。 我的基本原理是,如果仅使用$C线程,则内核将在进程忙于从驱动器中获取数据时处于空闲状态。但是,如果我不限制线程数(即make -j),那我就有浪费时间切换上下文,耗尽内存或什至更糟的风险。假设计算机具有$M千兆内存($M大约为10)。 所以我想知道是否有一个确定的策略来选择运行效率最高的线程数。


2
为何程序员要定义编程模型来代替C / POSIX进行并行处理?
新计算机体系结构的提供者经常尝试引入新的编程模型,例如,最近用于GPGPU的CUDA / OpenCL,并取代C / POSIX作为平台并行性的控制接口。(Poss&Koening,AM3:迈向面向多核的硬件Unix加速器,2015年) 为什么架构设计师尝试设计新的编程模型来代替C / POSIX进行并行计算?C / POSIX是不是非常适合多处理器,还是C / POSIX的原始作者在C / POSIX设计时就没有考虑并行计算的需求?还是程序员需要比C / POSIX所提供的功能更多的功能,从而诉诸于CUDA / OpenCL等新设计?

1
用于微控制器的RTOS的消息队列
我目前正在为微控制器编写RTOS。整个过程都是用C ++ 11编写的-如果有人感兴趣,则指向存储库的链接在底部。 当前,我正在编写一个类,该类是一个简单的数据队列,用于在线程之间(或在中断处理程序和线程之间或中断处理程序和其他中断处理程序之间)传递对象。通常,我尝试遵循在其他项目上找到的一些常见API,但是我没有找到具有emplace()功能并支持超时的并发队列的任何示例。 我一般的“问题”是我无法在这两个接口之间做出决定: (std::chrono::duration<Rep, Period>是模板化类型,为清晰起见,我省略了模板样板) 第一版: template<typename T> class FifoQueue { public: ... template<typename... Args> int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args); int tryPopFor(T&, std::chrono::duration<Rep, Period>); int tryPushFor(const T&, std::chrono::duration<Rep, Period>); int tryPushFor(T&&, std::chrono::duration<Rep, Period>); ... } 第二版: template<typename T> class FifoQueue { public: ... template<typename... Args> int tryEmplaceFor(std::chrono::duration<Rep, Period>, …



3
寻找分布式锁定模式
我需要为C#中的分布式系统提出一个自定义的递归对象锁定机制\模式。本质上,我有一个多节点系统。每个节点对n个状态段具有独占写入权限。至少一个其他节点上的只读也可以使用相同的状态。一些写入/更新必须在所有节点上都是原子的,而其他更新最终将通过后台复制过程,队列等变得一致。 对于原子更新,我正在寻找一种模式或示例,这些模式或示例可以有效地使我将对象标记为写锁定,然后可以分发,提交,回滚等。由于系统具有高级别的并发性,因此我假设我需要能够堆叠锁,这些锁要么超时,要么在释放锁之后展开。 事务或消息传递不是这个问题的重点,但是我已经为一些额外的上下文提供了它们。话虽如此,请随意阐明您认为需要的消息。 尽管我对实现全新产品不愿接受任何新想法,但是这是我所设想的模糊示例 thing.AquireLock(LockLevel.Write); //Do work thing.ReleaseLock(); 我在考虑使用扩展方法,可能看起来像这样 public static void AquireLock(this IThing instance, TupleLockLevel lockLevel) { //TODO: Add aquisition wait, retry, recursion count, timeout support, etc... //TODO: Disallow read lock requests if the 'thing' is already write locked //TODO: Throw exception when aquisition fails instance.Lock = lockLevel; } …

6
如果我使用锁,我的算法还能保持无锁状态吗?
无锁的一个常见定义是至少有一个进程可以取得进展。1个 如果我有一个简单的数据结构(例如队列),并受锁保护,那么一个进程始终可以取得进展,因为一个进程可以获取锁,执行所需操作并释放它。 那么它符合无锁的定义吗? 1参见例如M. Herlihy,V。Luchangco和M. Moir。无障碍同步:以双端队列为例。在《分布式计算》,2003年。“如果仅确保某些线程始终在进步,那么它将是无锁的”。

6
线程使用虚拟内存还是实际内存?
我正在尝试优化我的Linux服务器,使其每个进程处理10,000个线程,而现在仅处理382个线程。按照本文的说明,以下公式用于查找可能的总线程: number of threads = total virtual memory / (stack size*1024*1024) 这意味着线程将所有数据存储在虚拟内存中。据我所知,虚拟内存是Linux机器中的交换空间,交换空间存储在硬盘上,而不是RAM或缓存。 所以我的问题是我们的线程是否使用硬盘存储来处理/存储其数据。 如果是,那么这不会影响性能吗?我们可以通过将它们放在RAM或缓存中来提高性能吗?怎么样? 如果否,线程到底如何工作? 更新: 根据无用的回答,虚拟内存是一个大致包括以下内容的系统: 物理内存(RAM) 您附加的所有交换文件 硬件支持,用于在物理内存中不存在虚拟地址时将虚拟地址转换为物理地址并发出页面错误 (内核)软件支持:通过按需从交换中拉入页面来管理该硬件使用的查找表来处理那些页面错误 因此,虚拟内存上的所有内容都集中在RAM(真实内存)和硬盘(交换文件)上。正如詹姆斯在回答中所解释的那样,内核使用诸如LRU之类的算法对Ram与HDD做出了决定。

6
为什么将线程称为线程?
我了解一个进程是资源所有权和可执行指令的单元。线程允许一个进程通过多次执行共享其资源,并且由于与整个进程相关的所有开销,操作系统更容易调度线程。 但是为什么要命名线程?它是否有对字符串或执行交错的引用?即使这样,在我看来这也不是一个直观的术语。

1
许多阻塞VS单非阻塞工作者
假设有一个HTTP服务器接受连接,然后以某种方式等待标头被完全发送出去。我想知道实现它的最常用方法是什么,其余是什么利弊。我只能想到这些: 许多阻塞工人是好的,因为: 它反应更快。 引入新连接更容易(工作人员自己捡起它们,而不是局外人等到可以将其添加到同步列表中)。 随着连接数量的增加和减少,CPU使用率会自动平衡(无需付出任何额外的努力)。 更少的CPU使用率(阻塞的线程从执行循环中删除,不需要任何逻辑即可在客户端之间跳转)。 单一的非阻塞工人是好的,因为: 使用更少的内存。 较不易受懒客户端(连接到服务器并缓慢发送标头或根本不发送标头)的攻击。 如您所见,我认为多个工作线程总体上似乎是更好的解决方案。唯一的问题是,更容易攻击这种服务器。 编辑(更多研究): 我在网络上发现了一些资源(成千上万的线程和阻塞I / O-编写Java服务器的旧方法又是Paul Tyma的(又是更好的方法),这表明阻塞方法通常更好,但我仍然不太了解如何处理虚假连接。 PS不建议为该任务使用某些库或应用程序。我更想知道它是如何工作或可能起作用的,而不是使它起作用。 PSS我将逻辑分为多个部分,这一部分仅处理接受HTTP标头。不处理它们。

3
Linux中用于多核处理器的无锁IPC
我正在尝试找到一种在Linux上使用多核处理器在C语言下使用无锁IPC编写应用程序的方法。 假设我有进程1和进程2写入FIFO或共享内存。然后,进程3和进程4将从该共享内存或FIFO中读取。 使用无锁算法是否可能? 非常感谢您的指导。

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.