为什么这个程序出错?`对象同步方法是从一个不同步的代码块调用的

10 .net c# synchronization mutex

这段代码有什么问题?我得到一个'对象同步方法是从一个不同步的代码块调用'.我在google上发现了一个结果,我说我可能会在锁定之前释放一个互斥锁,但根据我的输出,情况并非如此.这是互斥代码,其间没有其他代码.

-edit-对不起伙计们,错误的粘贴.

我的输出

1W
1W
2W
Run Code Online (Sandbox Code Playgroud)

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace sqliteTest
{
    class Program
    {
        static volatile Mutex mut1 = new Mutex();
        static volatile Mutex mut2 = new Mutex();
        static void Main(string[] args)
        {
            mut1.WaitOne(); Console.WriteLine("1W");
            Thread oThread = new Thread(new ThreadStart(fn2));
            oThread.Start();
            mut1.WaitOne(); Console.WriteLine("1W");
            update(0);
        }
        static void fn2()
        {
            mut2.WaitOne(); Console.WriteLine("2W");
            mut1.ReleaseMutex(); Console.WriteLine("1R");
            mut2.WaitOne(); Console.WriteLine("2W");
            update(1);
            mut1.ReleaseMutex(); Console.WriteLine("1R");
        }
        static void update(int t)
        {
            mut2.ReleaseMutex(); Console.WriteLine("2R");
            if (t == 0)
            {
                mut1.WaitOne();
                Console.WriteLine("1W");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 22

这不是一个很好的错误消息,Windows生成它.它的真正含义是你在一个你不拥有的互斥锁上调用ReleaseMutex.你将通过第一个例外

static volatile Mutex mut2 = new Mutex(true);
Run Code Online (Sandbox Code Playgroud)

但是当它在mut1上调用ReleaseMutex时,它将在线程内部死亡,而它不属于它.不确定你要做什么,代码对我来说没有多大意义.

  • @HansPassant - 您非常有帮助,谢谢您的贡献! (3认同)

小智 5

是的,其他人是对的:这段代码没有任何意义.

但由于此页面在Google中排名较高(虽然没有帮助),我将所有搜索者重定向到这个关于线程同步的优秀网站:

http://www.albahari.com/threading/part2.aspx

Elmü


Mar*_*ers 4

您的代码似乎有很多问题。主线程启动一个新线程,然后调用update。在更新中,它尝试解锁 mutex2,但尚未锁定 mutex2,因此此操作会失败并出现异常。

即使这个错误被修复,其他线程也同样注定会失败。它会在锁定 mutex1 之前尝试释放它。

你想在这里做什么?您是否将 Mutex 与AutoResetEvent混淆了?

另外我猜测这两行是复制/粘贴错误,因为它们出现了两次:

        mut2.WaitOne(); Console.WriteLine("2W");
        mut1.ReleaseMutex(); Console.WriteLine("1R");
Run Code Online (Sandbox Code Playgroud)