你用线程做的最酷的事情是什么?

时间:2008-09-21 14:36:29

标签: multithreading

只是想知道

25 个答案:

答案 0 :(得分:27)

我让他们按照我的意愿工作了一次!那很酷!

答案 1 :(得分:13)

我不知道这是否重要,但对我来说,一个有效的多线程软件本身就很吸引人,而不是它们实现的目的。你有10,20,100名工人在你的程序中使用相同的基础设施(单身人士,文件等)。让一切与互斥体,信号量,上下文切换等协调工作是非常好的观察,就像成为一名经理,你的团队正在完美地合作。您阅读了应用程序日志,看到线程合作以实现共同目标,而且它非常棒。任何人都可以谈到这种感觉吗?

答案 2 :(得分:6)

我想说我已经巧妙地使用无锁数据结构并行化算法,以便在n核处理器上获得n倍的性能提升。但我从来没有实际需要,特别是因为我的大多数专业代码都是针对单核系统的。

几乎每次我使用多个线程,用任何语言,都是以下两个原因之一:

  • 系统(或第三方)提供阻止API,我需要一个异步API(或者至少让几个操作同时运行)。
  • 利用先发制人的优先级调度来保持一切美观和响应,而不必手工将所有慢速操作切成小块。

必要,但不是你称之为迷人的。

答案 3 :(得分:6)

我对线程毫无用处,我必须让我的女朋友重新缝上我的按钮。

答案 4 :(得分:3)

我最近被聘请帮助处理在Microsoft Windows系统上运行的大型复杂多线程应用程序,其中包含读取器/写入器锁定对象。这使得搜索死锁变得很困难,所以我编写了一个死锁检测对象,它在自己的线程中执行,只要它们试图锁定,成功或无法锁定和解锁,就会从锁定对象发送信息消息(使用PostThreadMessage)。

通过在真值表中查找不同的线程和共享锁及其状态,可以毫无疑问地找出死锁的原因和位置。

答案 5 :(得分:3)

我们曾经写过一个多线程应用程序,它基本上逐行读取文件并在内部数据库中查找是否有匹配,附加了一些数据并移动到下一行。但复杂性在于可能同时处理多个文件,并且可以搜索每个文件的多个记录。有一个管理器类知道有多少线程可用,并负责将可用的工作线程分配给每个文件(如果只有一个文件需要处理,它将收到所有40个线程,如果有5个文件,则取决于优先级,每个人都会收到40%的一小部分。我们首先使用了Async委托,但发现很难捕获异步线程中可能出现的异常,所以我们在.net中使用传统的线程启动。

关键是在管理器类中有一个ManualResetEvents集合,它由在工作类(线程)中属于公共属性的ManualResentEvents组成。当一个工作线程完成时,它将发出它的ManualResetEvent信号,它将由Manager类的.WaitAny()获取。然后管理员会知道其中一个线程已完成并将启动一个新线程。实际上它比这更复杂,但这是它所做的核心。

困难的部分是对其进行单元测试,以确保在任何给定时间运行正确数量的线程。我们的测试就好像队列中只有一个文件(获取所有40个线程),然后引入了另一个文件,并且线程的分配必须循环到20个文件的两个文件。我们有“模拟对象”,它基本上有一个线程睡眠参数,我们将传递一个值(以毫秒为单位)来控制每个线程需要多长时间来处理,这样我们就可以很好地知道何时进行断言或询问文件处理器,查看当前处理的线程数,记录数。还有一些测试会有两个文件以20个线程运行,然后一个文件将完成,并且所有记录线程将在第一个文件上完成,它们将被重新分配到第二个文件以帮助它更快地完成。

我确信这不是我们实际做的最清楚的解释,我真的需要写一篇关于它的博客文章。如果有人需要更多信息,请与我联系,我会尽力回答。

答案 6 :(得分:2)

我发现我可以创建一个FIFO,只有一个写入器,只有一个读取器,而不使用任何同步仪器。

(所以主从,有2 * n FIFO ..没有任何互斥/ semaphone !!)

如果您有一个长链表,则无需同步插入一端并在另一端删除。

诀窍是始终在列表中保留一个元素( - ; 代码非常小

当一个硬件人告诉我时,我的骄傲是'凹陷'。这很明显( - :

答案 7 :(得分:1)

我创建一个Windows服务来查询一堆RSS提要并将检索到的信息存储在数据库中。由于应用程序可以包含大量RSS提要,因此一个线程池每n次查询一次RSS包。
Thorsten79一样,最激动人心的部分是观察你的线程合作和工作作为一个团队一起。

答案 8 :(得分:1)

网络爬虫的分布式链接检查系统。由于网络抓取是一个非常容易线程化的解决方案,我不知道这是否重要......

我在大学期间编写了一个破解DES的算法,该算法运行在大学的自定义256 CPU机器上。这非常简洁,但实际上只是一种分而治之的问题。

答案 9 :(得分:1)

我用线程做的最有趣的事情之一是编写一个多线程应用程序来解决迷宫。

虽然没有什么突破性的,但它确实很有趣。

答案 10 :(得分:0)

具有异步输入/输出的简单客户端服务器。

答案 11 :(得分:0)

我在C ++中编写了一个小的fcgi servlet模型,它为每个新请求立即分配了一个新线程。

如果你不认为那很酷,你应该看看当我抽出3K req / s时发生了什么。我不小心忘了清理它们,即使你们自己终止并停止实际使用内存,它们仍然消耗寻址,我让应用程序快速重新开发比我更多的内存并停止创建线程。

(当时我在32位,并且在创建2 ^ 32个线程之后它确实停止了.Goodness知道它将用64位做什么)

此外,我为着名的命令rm -rf 创建了一个多线程(井,分叉)广度优先的fork-on-directory替换。主要是我对rm -rf感到沮丧,似乎等待IO回应yay / nay响应,这使得它在某些目录结构(例如squid缓存)上变慢。这段代码唯一真正的警告是它只具有娱乐价值,如果曾经在整个文件系统上使用过,它将是两种场景之间的竞赛:

  1. 磁盘被擦除使其无法使用,并可能删除允许您告诉它死亡的命令。
  2. 系统“Fork Bombing”由于大量的分叉率并使其高度操作密集,它甚至不再响应命令。
  3. 在“轰炸”的情况下,大量的产卵率可能导致递归rm自行停止(或者如果有的话击中Ulimit)

答案 12 :(得分:0)

这真的很香草,但它是迈向更有创意的线程的一个很好的踏脚石:

在upload-new-data-and-process-it-for-me类型请求中,请求线程接受数据并将其抛入队列,并且用户继续他们的快乐方式。一个或多个后台线程不断地使项目出列并以某种方式处理它们。

答案 13 :(得分:0)

噢 - 他们并不是复杂的迷宫。

迷宫是在一个数组中定义的,类似于:

String[] MazeArray = new String[5];

MazeArray[0] = "---X---X-------XF";
MazeArray[0] = "-X-X-X---XXXXXXX-";
MazeArray[0] = "-X-X-X-X-X---X---";
MazeArray[0] = "-X-X-X-XXX-X-X-X-";
MazeArray[0] = "SX---X-----X---X-";

当路径中有一个fork时,我会生成一个新的工作线程,并让该线程调查该路径。然后,通过一些基本逻辑,我可以确定最短路径,最长路径等。

列出的示例显然过于简化,但它应该说明一点。这是一个有趣的练习,如果你有几分钟的时间,你应该尝试一下。

伊恩

答案 14 :(得分:0)

我想为dos实现多线程是我用线程做的最酷的事情。

答案 15 :(得分:0)

我创建了一个带有无锁间隙通信的线程库,以简化多线程编程。仅限Delphi:OmniThreadLibrary

(为了给予应有的信用 - 我没有写出无锁结构,GJ确实如此。)

答案 16 :(得分:0)

Ian P,介意精心制作? AFAIK你不需要使用线程来解决迷宫,除非迷宫是如此复杂以至于等待时间变得如此难以忍受以至于你必须添加状态栏以便用户不会感到无聊并认为你的程序挂起。

答案 17 :(得分:0)

我在Java中编写了一个使用线程池的图像过滤框架。

我很惊讶即使在单处理器单核机器上,过滤器在多个并行线程中运行的速度也快得多。当我找到一些空闲时间时,我想弄清楚为什么会这样;我正在做的就是访问内存和数学计算。

线程摇滚(只要它们不锁定。)

也赞赏Java线程池。

答案 18 :(得分:0)

我为HDOS编写了一个多线程库。 HDOS是一个在HeathKit系统上运行的8位操作系统。我拦截了系统时钟滴答(每隔55毫秒,如果我没记错的话)并且有一个调度程序可以决定以循环方式运行下一个线程。当然,由于操作系统本身并非多线程,因此在任何给定时间内只允许一个线程在操作系统中。

我从未对它做过任何有用的事情。这只是一个有趣的项目我决定解决,看看我是否可以做到。

答案 19 :(得分:0)

我做了一个快速排序的实现,其中分区的左侧和右侧同时排序。它几乎是仅使用1个线程的相同代码的两倍。

答案 20 :(得分:0)

我写了一个无锁缓存,比最常见的基于锁的缓存库快10倍。有趣的是弄清楚如何进行复杂的CASing逻辑,并提出一种LRU的替代方案,它不会遭受锁定开销。

我还编写了一个分布式的master-worker框架,后来我将其抽象为原型,以支持fork-join和map-reduce。我需要在某些时候重做那些,因为它们不是生产质量,但它是一个非常有趣的转移。

我真的很想写一个SkipList数据结构,只是为了学习如何。已经有了一个核心实现,但是我很想深入了解它。它将纯粹丢弃代码,但具有教育意义。

答案 21 :(得分:0)

这不是多线程的应用程序,而是一个展示C#3.0功能的小片段,包括lambda和对象初始化器。不是你想到的,我敢肯定 - 但是“尽管如此,我已经完成了线程”。

new Thread(() => 
{
    // do stuff in a new thread's context
})
{
    Name = "Thread " + GetHashCode().ToString(),
    Priority = this.threadPriority
}
.Start();

答案 22 :(得分:0)

我在C#中为多线程编写了一个actor /消息传递的实现,因为我写过多线程已经非常简单了!编写本身就是非常有趣的消息队列的无锁数据结构。每个actor都没有一个线程,而是一个线程池,它循环遍历actor并运行每个actor。 因为多线程现在很容易,所以我有这个系统可以玩,我写了几个很酷的东西:
一个简单的套接字服务器/客户端演示应用
一个多线程的webcrawler(我要回到那个) 游戏的程序内容生成器 和其他一些事情,但他们都小而无聊

答案 23 :(得分:0)

多线程调用(第三方应用程序)不支持来自不同应用程序或线程的同时调用?虽然可以执行多个实例(这是我最终实现它的方式),但是某些应用程序操作无法在不同的应用程序实例上同时执行。

答案 24 :(得分:0)

parallel N-puzzle solver。它通过迭代加深搜索分叉来解决Npuzzle问题以实现搜索。这是在我设计的并行编程语言中完成的,这使得它很容易来分叉;程序中的整个魔法几乎隐藏在“fork parallel”操作符(|| ...)中你必须在代码中查找它。