views:

1846

answers:

3

What is wrong with this code? i get a 'Object synchronization method was called from an unsynchronized block of code'. I found one result on google that said i may be releasing a mutex before locking but according to my output this is not the case. Here is the mutex code without the other code in between.

-edit- sorry guys, wrong paste.

My output

1W
1W
2W

code

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");
            }
        }
    }
}
+1  A: 

Your code seems to have a number of problems. The main thread starts a new thread, then calls update. In update it tries to unlock mutex2, but it hasn't locked mutex2 yet, so this fails with an exception.

Even if this error is fixed, the other thread is equally doomed to failure. It will try to release mutex1 before it has locked it.

What are you trying to do here? Are you confusing Mutex with AutoResetEvent?

Also I'm guessing that these two lines are a copy/paste error because they appear twice:

        mut2.WaitOne(); Console.WriteLine("2W");
        mut1.ReleaseMutex(); Console.WriteLine("1R");
Mark Byers
sorry i accidentally skipped part of the code when i pasted. It may make more sense now.
acidzombie24
I still don't understand it. Now your main thread is locking mutex1 twice in a row, and then unlocking mutex2 which it doesn't own. What is the purpose of this? What are you actually trying to do?
Mark Byers
+2  A: 

It is not a great error message, Windows produces it. What it really means is that you are calling ReleaseMutex on a mutex that you don't own. You'll get past the first exception with

static volatile Mutex mut2 = new Mutex(true);

But then it will die inside the thread when it calls ReleaseMutex on mut1, which it doesn't own. Not sure what you're trying to do, the code doesn't make much sense to me.

Hans Passant
sorry i accidentally skipped part of the code when i pasted. It may make more sense now.
acidzombie24
Well, it is still the same problem. The thread that runs fn2() doesn't own the mut1 mutex, it can't release a mutex it doesn't own. Use a ManualResetEvent to signal other threads.
Hans Passant
ok your correct. That is the problem. It turns out i thought mutex are not recursive. I wanted semaphore. Using Semaphore(1,1); and fixing the .release function my code runs as expected.
acidzombie24
ok your correct. That is the problem. It turns out i thought mutex are not recursive. I wanted semaphore. Using Semaphore(1,1); and change .ReleaseMutex to Release the code runs exactly as expected.
acidzombie24
A: 

Hello

Yes the others are right: This code does not make any sense.

But as this page has a high ranking in Google (although it is not helpfull) I redirect all the searchers to this great site about Thread synchronization:

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

Elmü

Elmü