0

I have a class Library Application Called API. Inside which I have a method called SynchronizeMe.

 public class APIClass
    {
        object baton = new object();
        static int count = 0;
        public void SynchronizeMe()
        {
            while(true)
            {
                lock (baton)
                {
                    int temp = count;
                    Thread.Sleep(5000);
                    count = temp + 1;

                    Console.WriteLine("Thread Id " + Thread.CurrentThread.ManagedThreadId + " Name:" + Thread.CurrentThread.Name + " incremented count to " + count);
                }
                Thread.Sleep(1000);
            }

        }
    }

I have two console Application Thread1 and Thread2. Both of them calling SynchronizeMe Method. Like

 API.APIClass apicall = new API.APIClass();
 apicall.SynchronizeMe();

When I run this I see Both of them printing count start from 1. That means it is not syncronized. Am I understanding the concept of multi threading something wrong? Or code has issue? Or Thread in same application can only be synchronized. If I want to synchronize this way what is the way?

I think both Thread1 and Thread2 has different Instance of APIClass so Synchronization not Possible. Is there some way out?

Manjay_TBAG
  • 2,176
  • 3
  • 23
  • 43

2 Answers2

2

In the case where you have two separate console applications, locks using the lock keyword are not shared between them - lock is local to the individual process.

If you want to lock across processes you need to use a named mutex instead.

See http://www.c-sharpcorner.com/UploadFile/1d42da/threading-with-mutex/.

For cross process locking with a mutex, see http://mikeperetz.blogspot.co.uk/2013/12/cross-process-locking-using-named-mutex.html

Your code would look something like:

    public class APIClass
{
    private const string MutexName = "FAA9569-7DFE-4D6D-874D-19123FB16CBC-8739827-[SystemSpecicString]";
    private Mutex _globalMutex;
    private bool _owned = false;
    private int timeToWait = 1000;

    object baton = new object();
    static int count = 0;
    public void SynchronizeMe()
    {
        _globalMutex = new Mutex(true, MutexName, out _owned);
        while(true)
        {
            while (!_owned)
            {
                // did not get the mutex, wait for it.
                _owned = _globalMutex.WaitOne(timeToWait);
            }

            int temp = count;
            Thread.Sleep(5000);
            count = temp + 1;

            Console.WriteLine("Thread Id " + Thread.CurrentThread.ManagedThreadId + " Name:" + Thread.CurrentThread.Name + " incremented count to " + count);
            // release the mutex
            _globalMutex.ReleaseMutex();
            Thread.Sleep(1000);
        }

    }
}
user783836
  • 3,099
  • 2
  • 29
  • 34
  • While the synchronization will work, it will still not use the same counter variable between processes. – nvoigt Dec 23 '16 at 10:11
  • @nvoigt fair point and its not clear from the OP if that is the goal or if it was just to understand cross process synchronization – user783836 Dec 23 '16 at 10:14
  • @user783836 second thread is not able to acquire lock. Only thread1 is priniting value. second console gers nothing. – Manjay_TBAG Dec 23 '16 at 10:49
  • @TBAG this is because neither process ever yields the lock. Your code in the original question has the same problem. I have updated the code sample to yield the lock. Note however that, as @nvoigt pointed out, no variables (such as `count`) are shared across the processes. For that you'd need memory mapped files or similar. – user783836 Dec 23 '16 at 11:05
  • @user783836 Previous code was printing in both consoles. Share count variable is not important for me. – Manjay_TBAG Dec 23 '16 at 11:07
  • @TBAG, yes, because they were running as totally isolated processes. Now, with the mutex, the process with the mutex will block the other unless the lock is yielded – user783836 Dec 23 '16 at 11:08
  • @user783836 Getting following exception - Object synchronization method was called from an unsynchronized block of code. System.ApplicationException – Manjay_TBAG Dec 23 '16 at 11:10
0

Two processes (or rather two app domains) will load two totally separate copies of your library.

So not only will your lock only lock the copy of the calling assembly, your count variable will exist as two separate copies as well.

You can have process-agnostic synchronization with for example a mutex but you still need to find a way to share that counter. That can be as simple as keeping it in a file or registry entry, or you could use a database. But if you want to keep it in memory, you will need to start a third process instead of loading a copy of each library into your existing processes. That means you will need inter process communication.

Community
  • 1
  • 1
nvoigt
  • 75,013
  • 26
  • 93
  • 142