Tag: multithreading

如何正确等待,直到BackgroundWorker完成?

观察下面的一段代码: var handler = GetTheRightHandler(); var bw = new BackgroundWorker(); bw.RunWorkerCompleted += OnAsyncOperationCompleted; bw.DoWork += OnDoWorkLoadChildren; bw.RunWorkerAsync(handler); 现在假设我想等到bw完成工作。 什么是正确的方法呢? 我的解决办法是: bool finished = false; var handler = GetTheRightHandler(); var bw = new BackgroundWorker(); bw.RunWorkerCompleted += (sender, args) => { OnAsyncOperationCompleted(sender, args); finished = true; }); bw.DoWork += OnDoWorkLoadChildren; bw.RunWorkerAsync(handler); int timeout = N; while (!finished […]

在multithreading场景中调用Dictionary对象的set_item方法时抛出NullReferenceException

我们的网站有一个configuration页面,如“config.aspx”,当页面初始化时会从configuration文件中加载一些信息。 为了caching加载的信息,我们提供了一个工厂类,我们调用工厂的一个公共方法来获取页面加载时的configuration实例。 但有时候,当应用程序池重新启动时,我们在事件日志中发现了一些错误信息,例如: 消息:对象引用未设置为对象的实例。 堆栈:在System.Collections.Generic.Dictionary`2.Insert(TKey键,TValue值,布尔添加) 在System.Collections.Generic.Dictionary`2.set_Item(TKey键,TValue值) 在ObjectFactory.GetInstance(string键) 在config.Page_Load(对象发件人,EventArgs e) 在System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,Object o,Object t,EventArgs e) 在System.Web.Util.CalliEventHandlerDelegateProxy.Callback(对象发件人,EventArgs e) 在System.Web.UI.Control.OnLoad(EventArgs e) 在System.Web.UI.Control.LoadRecursive() 在System.Web.UI.Page.ProcessRequestMain(布尔includeStagesBeforeAsyncPoint,布尔includeStagesAfterAsyncPoint) 工厂类实现如下: public static class ObjectFactory { private static object _InternalSyncObject; private static Dictionary _Instances; private static object InternalSyncObject { get { if (_InternalSyncObject == null) { var @object = new object(); Interlocked.CompareExchange(ref _InternalSyncObject, @object, null); […]

WaitAll不支持STA线程上的多个句柄

为什么我得到这个错误信息? “WaitAll在STA线程上的多个句柄不被支持”。 我应该使用[MTAThreadAttribute]属性? 更新:不用WPF应用程序! 注意:错误在WaitHandle.WaitAll(doneEvents); 我正在使用一个标准的WPF项目 。 private void Search() { const int CPUs = 2; var doneEvents = new ManualResetEvent[CPUs]; // Configure and launch threads using ThreadPool: for (int i = 0; i < CPUs; i++) { doneEvents[i] = new ManualResetEvent(false); var f = new Indexer(Paths[i], doneEvents[i]); ThreadPool.QueueUserWorkItem(f.WaitCallBack, i); } // Wait for all […]

进程,线程,绿色线程,原线程,纤维,协程:有什么区别?

我正在阅读并发。 我的脑海中有一些混淆相似的定义。 即: stream程 主题 “绿色线索” Protothreads 纤维 协同程序 Go语言中的“Goroutines” 我的印象是,区别在于:(1)是真正的并行还是多路复用; (2)是否在CPU,操作系统或程序中进行pipe理; 和(3..5)其他一些我无法识别的东西。 对于这些并行性方法之间的差异,有没有一个简洁而明确的指导?

我如何在Scala中执行多个任务?

我有50,000个任务,想用10个线程执行它们。 在Java中,我应该创buildExecuters.threadPool(10)并传递runnable,然后等待处理所有。 据我所知,Scala对于这个任务特别有用,但我无法在文档中find解决scheme。

ExectuorService与ThreadPoolExecutor(使用LinkedBlockingQueue)

我正在开发一个Multithreaded项目,在该项目中,我需要生成多个线程来测量我的客户端代码的端到端性能,因为我正在进行负载和性能testing。 所以我创build了下面使用ExecutorService代码 – 下面是使用ExecutorService的代码 – public class MultithreadingExample { public static void main(String[] args) throws InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(20); for (int i = 0; i < 100; i++) { executor.submit(new NewTask()); } executor.shutdown(); executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); } } class NewTask implements Runnable { @Override public void run() { //Measure the end to end latency […]

从Android的辅助线程调用主线程

如何从Android的辅助线程调用主线程?

为什么我的日志logging库会使性能testing运行得更快?

我花了一年的时间开发一个C ++的日志logging库,并且考虑到性能。 为了评估性能,我开发了一套基准testing程序 ,将我的代码与其他库进行比较,其中包括根本不执行任何日志logging的基本情况。 在我的上一个基准testing中,我测量了一个CPU密集型任务的总运行时间。 然后我可以比较一下时间来确定我的图书馆有多less开销。 这个条形图显示了与我的非测井基础案例相比的差异。 正如你所看到的,我的库(“鲁莽”)增加了负面开销 (除非所有4个CPU核心都忙)。 当启用日志function时,程序运行速度比停用时快大约半秒。 我知道我应该尝试把这个问题分解成一个简单的案例,而不是问一个4000线的项目。 但是有那么多的地方要去掉什么东西,没有一个假设,当我试图隔离它的时候,我会让问题消失。 我可能再花一年时间来做这件事。 我希望堆栈溢出的集体专业知识会使这个问题变得更加简单,或者对于那些比我更有经验的人来说,这个原因是显而易见的。 关于我的图书馆和基准的一些事实: 该库由一个将日志参数推送到无锁队列(Boost.Lockless)的前端API和一个执行string格式化并将日志条目写入磁盘的后端线程组成。 时间是基于简单地在程序的开始和结束处调用std::chrono::steady_clock::now() ,并打印差异。 该基准testing是在一个4核英特尔CPU(i7-3770K)上运行的。 基准程序计算一个1024×1024 Mandelbrot分形并logging每个像素的统计信息,即它写入大约一百万条日志条目。 单个工作线程的总运行时间约为35秒。 所以速度增加大概是1.5%。 基准testing产生一个输出文件(这不是定时代码的一部分),它包含了生成的Mandelbrot分形。 我已经validation,日志打开和closures时产生相同的输出。 基准testing运行了100次(所有基准testing库都需要大约10个小时)。 条形图显示平均时间,误差棒显示四分位间距。 Mandelbrot计算的源代码 基准的源代码 。 代码库和文档的根 。 我的问题是,我怎样才能解释当我的日志库启用明显的速度增加? 编辑 :这是在尝试了评论中给出的build议后解决的。 我的日志对象是在基准testing的第24行创build的。 显然,当LOG_INIT()触及日志对象时,它会触发页面错误,导致图像缓冲区的一些或全部页面被映射到物理内存。 我仍然不确定为什么这会将性能提高近半秒; 即使没有日志对象,在mandelbrot_thread()函数中发生的第一件事是写入图像缓冲区的底部,这应该具有类似的效果。 但是,在任何情况下,在开始基准testing之前用memset()清除缓冲区会使得一切更加理智。 目前的基准在这里 其他我试过的事情是: 用oprofile分析器运行它。 即使在将工作放大10分钟左右之后,我也从来没有能够在任何时间注册。 几乎所有的时间都在Mandelbrot计算的内部循环中。 但是,也许现在我知道页面错误,我可以用不同的方式解释它们。 我没有想到要检查图像写入是否花费了不成比例的时间。 卸下锁。 这确实对性能有显着的影响,但结果仍然很奇怪,无论如何,我无法对任何multithreading变体进行更改。 比较生成的汇编代码。 有差异,但日志build设显然是做更多的事情。 没有什么是一个明显的表演杀手。

为什么不在System.Double和System.Long上挥发?

一个像我这样的问题已经被问到 ,但我的情况有点不一样。 问题是,“为什么在C#typesSystem.Double和System.Int64等中不允许使用volatile关键字? 乍一看,我回答了我的同事,“在32位机器上,这些types至less需要两个滴答才能进入处理器,而.Net框架的目的是抽象出处理器的具体细节。 “ 他回应说:“如果因为处理器特定的问题阻止你使用某个function,那么它就不是抽象的东西!” 他暗示着一个处理器特定的细节不应该显示给一个使用像程序员那样“抽象”细节的框架的人。 所以,框架(或者C#)应该把这些东西抽象出来,并且为System.Double等提供相同的保证(无论是信号量,内存屏障还是其他)。 我认为框架不应该增加信号量的易变性,因为程序员并不期望这样的关键字有这样的开销,因为信号量对于32位types不是必需的。 64位types的更大开销可能会令人吃惊,因此,对于.Net框架来说,更好的办法就是不允许它,并且如果开销可以接受的话,让你在更大的types上做自己的信号量。 这导致我们调查volatile关键字的全部内容。 (见本页)。 该页面在说明中指出: 在C#中,在字段上使用volatile修饰符可以保证对该字段的所有访问使用VolatileRead或VolatileWrite。 嗯….. VolatileRead和VolatileWrite都支持我们的64位types! 我的问题是, “为什么在C#types的System.Double和System.Int64等中不允许使用volatile关键字?

在Java中的指令重新sorting&发生之前的关系

在“Java并发实践”一书中,我们多次被告知,我们程序的指令可以由编译器,JVM在运行时甚至处理器进行重新sorting。 所以我们应该假定被执行的程序不会按照我们在源代码中指定的顺序执行它的指令。 然而,讨论Java内存模型的最后一章提供了“ 发生之前”规则的列表,指示JVM保留哪些指令sorting。 第一条规则是: “程序顺序规则。线程中的每个动作都发生在该线程中的每个动作之前,这些动作在程序顺序中稍后进行。 我相信“程序顺序”是指源代码。 我的问题是 :假设这条规则,我想知道什么样的指令可能会被重新sorting。 “行动”定义如下: Java内存模型是根据操作来指定的,包括对variables的读写操作,监视器的locking和解锁,以及与线程的启动和连接。 JMM定义了在程序中的所有操作之前发生的部分sorting。 为了保证执行动作B的线程可以看到动作A的结果(不pipeA和B是否出现在不同的线程中),在A和B之间的关系之前必定有一个事件发生。如果在两个操作,JVM可以自由地对其进行重新sorting。 其他提到的订单规则是: 监视locking规则。 在同一监视器锁上的每个后续锁之前,都会发生监视器锁的解锁。 易变的规则。 写入到易失性字段会在每次后续读取相同字段之前发生。 线程启动规则。 线程上的Thread.start调用在启动线程中的每个操作之前发生。 线程终止规则。 线程中的任何动作发生在任何其他线程检测到线程已终止之前,无论是从Thread.join成功返回还是由Thread.isAlive返回false。 中断规则。 另一个线程上的线程调用中断发生在被中断的线程检测到中断之前(通过抛出InterruptedException或者调用isInterrupted或者中断)。 终结者规则。 对象的构造函数的结束发生在该对象的终结器开始之前。 及物。 如果A发生在B之前,B发生在C之前,那么A发生在C之前。