以2种方法同步2个互斥体

问题描述 投票:0回答:1

我有 TIC 和 TAC 两种方法,它们只输出“TIC”或“TAC”。我的目标是创建 TIC 和 TAC 的多个线程之后。结果会依次输出:TIC, TAC, TIC...

我在这里创建线程。

Class1 a = new ();

Thread thread1 = new Thread(() => a.TIC());
Thread thread2 = new Thread(() => a.TIC());
Thread thread3 = new Thread(() => a.TIC());

Thread thread4 = new Thread(() => a.TAC());
Thread thread5 = new Thread(() => a.TAC());
Thread thread6 = new Thread(() => a.TAC());

thread3.Start();
thread5.Start();
thread2.Start();
thread6.Start();
thread4.Start();
thread1.Start();

thread1.Join();
thread2.Join();
thread3.Join();
thread4.Join();
thread5.Join();
thread6.Join();

这里是 TIC 和 TAC 方法

public class Class1
{
    public Mutex mutexTIC = new Mutex(true);
    public Mutex mutexTAC = new Mutex(false);

    public void TIC()
    {
        mutexTIC.WaitOne();
        Console.WriteLine("TIC");

        mutexTAC.ReleaseMutex();
    }

    public void TAC()
    {
        mutexTAC.WaitOne();
        Console.WriteLine("TAC");
        mutexTIC.ReleaseMutex();
    }
}

我还尝试添加锁,添加互斥体作为参数,尝试使用事件。 但每次我收到此 System.ApplicationException: '对象同步方法是从不同步的代码块调用的。'。我不知道如何解决它。 对于任何不清楚的地方,我深表歉意。希望我解释得足够多。

c# .net multithreading mutex thread-synchronization
1个回答
0
投票

您收到此异常是因为您错误地使用了

Mutex
:您在创建
mutexTIC
的主线程上获取
Class1
,但随后尝试在不同的线程上释放它。存在此限制是因为
Mutex
包装了一个内核互斥对象,该对象(至少在 Windows 上)强制执行这些线程规则。使用限制较少的规则的托管同步对象,而不是
Mutex
,例如
SemaphoreSlim
:

// in Class1:
public SemaphoreSlim mutexTIC = new (1, 1);
public SemaphoreSlim mutexTAC = new (0, 1);

public void TIC()
{
    mutexTIC.Wait();
    Console.WriteLine("TIC");

    mutexTAC.Release();
}

public void TAC()
{
    mutexTAC.Wait();
    Console.WriteLine("TAC");
    mutexTIC.Release();
}

请注意,此代码作为玩具示例很好,但如果

TIC()
TAC()
做了一些可能引发异常的重要事情,则需要非常小心异常和错误处理,以免丢失信号量计数并造成僵局。

© www.soinside.com 2019 - 2024. All rights reserved.