同步翻过线程/原子检查? [英] Synchronization accross threads / atomic checks?

查看:103
本文介绍了同步翻过线程/原子检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个方法调用的任何线程(例如为了线程B)可以调用,这将在其执行特定的指定点的主要执行的线程(THEAD A)上执行。

I need to create an method invoker that any thread (Thread B for example sake) can call, which will execute on the main executing thread (Thead A) at a specific given point in its execution.

用法示例将如下所示:

static Invoker Invoker = new Invoker();

static void ThreadA()
{
    new Thread(ThreadB).Start();

    Thread.Sleep(...); // Hypothetic Alpha

    Invoker.Invoke(delegate { Console.WriteLine("Action"); }, true);

    Console.WriteLine("Done");

    Console.ReadLine();
}

static void ThreadB()
{
    Thread.Sleep(...); // Hypothetic Beta

    Invoker.Execute();
}

调用程序类看起来是这样的:

The Invoker class looks like this:

public class Invoker
{
    private Queue<Action> Actions { get; set; }

    public Invoker()
    {
        this.Actions = new Queue<Action>();
    }

    public void Execute()
    {
        while (this.Actions.Count > 0)
        {
            this.Actions.Dequeue()();
        }
    }

    public void Invoke(Action action, bool block = true)
    {
        ManualResetEvent done = new ManualResetEvent(!block);

        this.Actions.Enqueue(delegate
        {
            action();
            if (block) done.Set();
        });

        if (block)
        {
            done.WaitOne();
        }
    }
}

这工作正常,在大多数情况下,虽然不会,如果因任何理由,执行(因此设置)的前<$ C $完成C> WaitOne的,在这种情况下,它只是冻结(它允许线程继续进行,然后块)。这可能如果阿尔法>>测试版再现。

This works fine in most cases, although it won't if, for any reason, the execution (and therefore the Set) is done before the WaitOne, in which case it will just freeze (it allows for the thread to proceed, then blocks). That could be reproduced if Alpha >> Beta.

我可以使用布尔和诸如此类的东西,但我从来没有得到一个真正的原子安全在这里。我尝试了一些修正,但他们不会的情况下工作,在那里测试版>>阿尔法。

I can use booleans and whatnot, but I'm never getting a real atomic safety here. I tried some fixes, but they wouldn't work in the case where Beta >> Alpha.

我也想过锁定周围都将Invoker.Execute和Invoker.Invoke方法,使我们在保证执行不enqueing和等待的发生。然而,问题在于,该锁还englobes的WaitOne的,因此无法完成(死锁)。

I also thought of locking around both the Invoker.Execute and Invoker.Invoke methods so that we are guaranteed that the execution does not occur between enqueing and waiting. However, the problem is that the lock also englobes the WaitOne, and therefore never finishes (deadlock).

如何去获得绝对安全的原子在这种模式?

How should I go about getting absolute atomic safety in this paradigm?

请注意:这的确是我这个设计工作,从外部依赖的要求。因此,改变设计是不是一个真正的选择。

Note: It really is a requirement that I work with this design, from external dependencies. So changing design is not a real option.

修改:我也忘了提,我希望有一个阻塞行为(根据布尔块),直到该委托是在调用执行调用。

EDIT: I did forget to mention that I want a blocking behaviour (based on bool block) until the delegate is executed on the Invoke call.

推荐答案

使用信号量(超薄)而不是的ManualResetEvent

使用的最大计数 1 ,呼叫 WaitOne的()调用线程,并调用创建一个信号量发行()的委托。

Create a semaphore with an maximum count of 1, call WaitOne() in the calling thread, and call Release() in the delegate.

如果你已经叫发行() WaitOne的()应立即返回。

If you've already called Release(), WaitOne() should return immediately.

请务必的Dispose()它时,你就大功告成了,preferably在使用块。照片 如果是假的,你不应该摆在首位创建它(尽管对于 SemaphoreSlim ,这不是那么糟糕)。

Make sure to Dispose() it when you're done, preferably in a using block.
If block is false, you shouldn't create it in the first place (although for SemaphoreSlim, that's not so bad).

这篇关于同步翻过线程/原子检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆